package.xml0000664000175000017500000021577612673034026013060 0ustar jmikolajmikola mongodb pecl.php.net MongoDB driver for PHP The purpose of this driver is to provide exceptionally thin glue between MongoDB and PHP, implementing only fundemental and performance-critical components necessary to build a fully-functional MongoDB driver. Hannes Magnusson bjori bjori@php.net yes Jeremy Mikola jmikola jmikola@php.net yes Derick Rethans derick derick@php.net yes 2016-03-18 1.1.5 1.1.5 stable stable Apache License * PHPC-632: Define MONGOC_NO_AUTOMATIC_GLOBALS when bundling libmongoc 5.4.0 7.99.99 1.4.8 mongodb mongodb-1.1.5/scripts/centos/ldap/Domain.ldif0000664000175000017500000000012712673034026020757 0ustar jmikolajmikoladn: dc=10gen,dc=me objectClass: dcObject objectClass: organization dc: 10gen o : 10gen mongodb-1.1.5/scripts/centos/ldap/Users.ldif0000664000175000017500000000010612673034026020646 0ustar jmikolajmikoladn: ou=Users,dc=10gen,dc=me ou: Users objectClass: organizationalUnit mongodb-1.1.5/scripts/centos/ldap/basics.ldif0000664000175000017500000000024412673034026021014 0ustar jmikolajmikoladn: dc=10gen,dc=me objectclass: dcObject objectclass: organization o: MongoDB dc: 10gen dn: cn=Manager,dc=10gen,dc=me objectclass: organizationalRole cn: Manager mongodb-1.1.5/scripts/centos/ldap/install.sh0000664000175000017500000000114112673034026020707 0ustar jmikolajmikolayum -y update yum -y install openldap-servers openldap-clients openldap-devel python-devel gcc cyrus-sasl-plain xfsprogs net-snmp ps-misc wget python-ldap service slapd stop service slapd start #just in case sleep 10 ldapadd -Y EXTERNAL -H ldapi:/// -f /phongo/scripts/centos/ldap/pw.ldif # Add our specifics ldapadd -x -D "cn=Manager,dc=10gen,dc=me" -w password -f /phongo/scripts/centos/ldap/Domain.ldif ldapadd -x -D "cn=Manager,dc=10gen,dc=me" -w password -f /phongo/scripts/centos/ldap/Users.ldif # Add the users python /phongo/scripts/centos/ldap/ldapconfig.py -f /phongo/scripts/centos/ldap/users mongodb-1.1.5/scripts/centos/ldap/mongod.ldif0000664000175000017500000001027212673034026021035 0ustar jmikolajmikola# # See slapd-config(5) for details on configuration options. # This file should NOT be world readable. # dn: cn=config objectClass: olcGlobal cn: config olcArgsFile: /var/run/openldap/slapd.args olcPidFile: /var/run/openldap/slapd.pid # # TLS settings # olcTLSCACertificatePath: /etc/openldap/certs olcTLSCertificateFile: "OpenLDAP Server" olcTLSCertificateKeyFile: /etc/openldap/certs/password # # Do not enable referrals until AFTER you have a working directory # service AND an understanding of referrals. # #olcReferral: ldap://root.openldap.org # # Sample security restrictions # Require integrity protection (prevent hijacking) # Require 112-bit (3DES or better) encryption for updates # Require 64-bit encryption for simple bind # #olcSecurity: ssf=1 update_ssf=112 simple_bind=64 # # Load dynamic backend modules: # - modulepath is architecture dependent value (32/64-bit system) # - back_sql.la backend requires openldap-servers-sql package # - dyngroup.la and dynlist.la cannot be used at the same time # #dn: cn=module,cn=config #objectClass: olcModuleList #cn: module #olcModulepath: /usr/lib/openldap #olcModulepath: /usr/lib64/openldap #olcModuleload: accesslog.la #olcModuleload: auditlog.la #olcModuleload: back_dnssrv.la #olcModuleload: back_ldap.la #olcModuleload: back_mdb.la #olcModuleload: back_meta.la #olcModuleload: back_null.la #olcModuleload: back_passwd.la #olcModuleload: back_relay.la #olcModuleload: back_shell.la #olcModuleload: back_sock.la #olcModuleload: collect.la #olcModuleload: constraint.la #olcModuleload: dds.la #olcModuleload: deref.la #olcModuleload: dyngroup.la #olcModuleload: dynlist.la #olcModuleload: memberof.la #olcModuleload: pcache.la #olcModuleload: ppolicy.la #olcModuleload: refint.la #olcModuleload: retcode.la #olcModuleload: rwm.la #olcModuleload: seqmod.la #olcModuleload: smbk5pwd.la #olcModuleload: sssvlv.la #olcModuleload: syncprov.la #olcModuleload: translucent.la #olcModuleload: unique.la #olcModuleload: valsort.la # # Schema settings # dn: cn=schema,cn=config objectClass: olcSchemaConfig cn: schema include: file:///etc/openldap/schema/core.ldif include: file:///etc/openldap/schema/corba.schema include: file:///etc/openldap/schema/cosine.ldif include: file:///etc/openldap/schema/duaconf.schema include: file:///etc/openldap/schema/dyngroup.schema include: file:///etc/openldap/schema/inetorgperson.ldif include: file:///etc/openldap/schema/java.schema include: file:///etc/openldap/schema/misc.schema include: file:///etc/openldap/schema/nis.ldif include: file:///etc/openldap/schema/openldap.ldif include: file:///etc/openldap/schema/ppolicy.schema include: file:///etc/openldap/schema/collective.schema # # Frontend settings # dn: olcDatabase=frontend,cn=config objectClass: olcDatabaseConfig olcDatabase: frontend # # Sample global access control policy: # Root DSE: allow anyone to read it # Subschema (sub)entry DSE: allow anyone to read it # Other DSEs: # Allow self write access # Allow authenticated users read access # Allow anonymous users to authenticate # #olcAccess: to dn.base="" by * read #olcAccess: to dn.base="cn=Subschema" by * read #olcAccess: to * # by self write # by users read # by anonymous auth # # if no access controls are present, the default policy # allows anyone and everyone to read anything but restricts # updates to rootdn. (e.g., "access to * by * read") # # rootdn can always read and write EVERYTHING! # # # Configuration database # dn: olcDatabase=config,cn=config objectClass: olcDatabaseConfig olcDatabase: config olcAccess: to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,c n=auth" manage by * none # # Server status monitoring # dn: olcDatabase=monitor,cn=config objectClass: olcDatabaseConfig olcDatabase: monitor olcAccess: to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,c n=auth" read by dn.base="cn=Manager,dc=10gen,dc=me" read by * none # # Backend database definitions # dn: olcDatabase=hdb,cn=config objectClass: olcDatabaseConfig objectClass: olcHdbConfig olcDatabase: hdb olcSuffix: dc=10gen,dc=me olcRootDN: cn=Manager,dc=10gen,dc=me olcRootPW: {SSHA}t3hTZGC4FTOS6AnTa76aX7HRtt1IDqFM olcDbDirectory: /var/lib/ldap olcDbIndex: objectClass eq,pres olcDbIndex: ou,cn,mail,surname,givenname eq,pres,sub mongodb-1.1.5/scripts/centos/ldap/pw.ldif0000664000175000017500000000117312673034026020200 0ustar jmikolajmikoladn: olcDatabase={0}config,cn=config changetype: modify replace: olcRootPW olcRootPW: {SSHA}t3hTZGC4FTOS6AnTa76aX7HRtt1IDqFM - replace: olcRootDN olcRootDN: cn=Manager,dc=10gen,dc=me dn: olcDatabase={2}bdb,cn=config changetype: modify replace: olcRootPW olcRootPW: {SSHA}t3hTZGC4FTOS6AnTa76aX7HRtt1IDqFM - replace: olcSuffix olcSuffix: dc=10gen,dc=me - replace: olcRootDN olcRootDN: cn=Manager,dc=10gen,dc=me dn: olcDatabase={1}monitor,cn=config changetype: modify replace: olcAccess olcAccess: {0}to * by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" read by dn.base="cn=Manager,dc=10gen,dc=me" read by * none mongodb-1.1.5/scripts/centos/ldap/saslauthd.conf0000664000175000017500000000014312673034026021545 0ustar jmikolajmikolaldap_servers: ldap://localhost:389 ldap_search_base: ou=Users,dc=10gen,dc=me ldap_filter: (uid=%u) mongodb-1.1.5/scripts/centos/ldap/users0000664000175000017500000000002612673034026017772 0ustar jmikolajmikolabugs features dbadmin mongodb-1.1.5/scripts/centos/essentials.sh0000664000175000017500000000036212673034026020477 0ustar jmikolajmikola# Tools you can't live without sudo yum install -y git vim # I can't stand emacs echo 'set -o vi' | sudo tee /etc/profile.d/vishell.sh # Who knows how to configure RHEL at all anyway? sudo service iptables stop sudo chkconfig iptables off mongodb-1.1.5/scripts/freebsd/essentials.sh0000664000175000017500000000057512673034026020624 0ustar jmikolajmikola# Update ports sudo portsnap fetch extract update # Minimum required PHP install + pecl sudo pkg install -y pcre php56 php56-openssl php56-json php56-zlib pear autoconf pkgconf cyrus-sasl # We need vim. git requires curl. mongoc requires libtool and automake sudo pkg install -y vim git curl libtool automake # I can't stand emacs echo 'set -o vi' | sudo tee -a /etc/profile mongodb-1.1.5/scripts/freebsd/phongo.sh0000664000175000017500000000047312673034026017741 0ustar jmikolajmikolals -1 /phongo/mongodb*.tgz | sort -n -r | xargs sudo pecl install -f 2>&1 > /phongo/.build if test $? -eq 0; then php -m | grep -q mongodb || echo "extension=mongodb.so" | sudo tee -a /usr/local/etc/php/extensions.ini pecl run-tests -q -p mongodb 2>&1 > /phongo/.tests else tail -n50 /phongo/.build exit 3 fi mongodb-1.1.5/scripts/presets/replicaset-30.json0000664000175000017500000000266512673034026021441 0ustar jmikolajmikola{ "id": "REPLICASET_30", "name": "mongod", "members": [ { "procParams": { "dbpath": "/tmp/REPLICASET/3100/", "ipv6": true, "logappend": true, "logpath": "/tmp/REPLICASET/3100/mongod.log", "nohttpinterface": true, "journal": true, "noprealloc": true, "nssize": 1, "port": 3100, "smallfiles": true, "setParameter": {"enableTestCommands": 1} }, "rsParams": { "priority": 99, "tags": { "ordinal": "one", "dc": "pa" } }, "server_id": "RS-30-one" }, { "procParams": { "dbpath": "/tmp/REPLICASET/3101/", "ipv6": true, "logappend": true, "logpath": "/tmp/REPLICASET/3101/mongod.log", "nohttpinterface": true, "journal": true, "noprealloc": true, "nssize": 1, "port": 3101, "smallfiles": true, "setParameter": {"enableTestCommands": 1} }, "rsParams": { "priority": 1.1, "tags": { "ordinal": "two", "dc": "nyc" } }, "server_id": "RS-30-two" }, { "procParams": { "dbpath": "/tmp/REPLICASET/3102/", "ipv6": true, "logappend": true, "logpath": "/tmp/REPLICASET/3002/mongod.log", "nohttpinterface": true, "journal": true, "noprealloc": true, "nssize": 1, "port": 3102, "smallfiles": true, "setParameter": {"enableTestCommands": 1} }, "rsParams": { "arbiterOnly": true }, "server_id": "RS-30-arbiter" } ], "version": "30-release" } mongodb-1.1.5/scripts/presets/replicaset.json0000664000175000017500000000261712673034026021216 0ustar jmikolajmikola{ "id": "REPLICASET", "name": "mongod", "members": [ { "procParams": { "dbpath": "/tmp/REPLICASET/3000/", "ipv6": true, "logappend": true, "logpath": "/tmp/REPLICASET/3000/mongod.log", "nohttpinterface": true, "journal": true, "noprealloc": true, "nssize": 1, "port": 3000, "smallfiles": true, "setParameter": {"enableTestCommands": 1} }, "rsParams": { "priority": 99, "tags": { "ordinal": "one", "dc": "pa" } }, "server_id": "RS-one" }, { "procParams": { "dbpath": "/tmp/REPLICASET/3001/", "ipv6": true, "logappend": true, "logpath": "/tmp/REPLICASET/3001/mongod.log", "nohttpinterface": true, "journal": true, "noprealloc": true, "nssize": 1, "port": 3001, "smallfiles": true, "setParameter": {"enableTestCommands": 1} }, "rsParams": { "priority": 1.1, "tags": { "ordinal": "two", "dc": "nyc" } }, "server_id": "RS-two" }, { "procParams": { "dbpath": "/tmp/REPLICASET/3002/", "ipv6": true, "logappend": true, "logpath": "/tmp/REPLICASET/3002/mongod.log", "nohttpinterface": true, "journal": true, "noprealloc": true, "nssize": 1, "port": 3002, "smallfiles": true, "setParameter": {"enableTestCommands": 1} }, "rsParams": { "arbiterOnly": true }, "server_id": "RS-arbiter" } ] } mongodb-1.1.5/scripts/presets/standalone-24.json0000664000175000017500000000053512673034026021433 0ustar jmikolajmikola{ "name": "mongod", "id" : "STANDALONE_24", "procParams": { "dbpath": "/tmp/standalone-24/", "ipv6": true, "logappend": true, "logpath": "/tmp/standalone-24/mongod.log", "journal": true, "port": 2500, "setParameter": {"enableTestCommands": 1} }, "version": "24-release" } mongodb-1.1.5/scripts/presets/standalone-26.json0000664000175000017500000000053512673034026021435 0ustar jmikolajmikola{ "name": "mongod", "id" : "STANDALONE_26", "procParams": { "dbpath": "/tmp/standalone-26/", "ipv6": true, "logappend": true, "logpath": "/tmp/standalone-26/mongod.log", "journal": true, "port": 2600, "setParameter": {"enableTestCommands": 1} }, "version": "26-release" } mongodb-1.1.5/scripts/presets/standalone-30.json0000664000175000017500000000053512673034026021430 0ustar jmikolajmikola{ "name": "mongod", "id" : "STANDALONE_30", "procParams": { "dbpath": "/tmp/standalone-30/", "ipv6": true, "logappend": true, "logpath": "/tmp/standalone-30/mongod.log", "journal": true, "port": 2700, "setParameter": {"enableTestCommands": 1} }, "version": "30-release" } mongodb-1.1.5/scripts/presets/standalone-auth.json0000664000175000017500000000061012673034026022141 0ustar jmikolajmikola{ "name": "mongod", "id" : "STANDALONE_AUTH", "auth_key": "secret", "login": "root", "password": "toor", "procParams": { "dbpath": "/tmp/standalone-auth/", "ipv6": true, "logappend": true, "logpath": "/tmp/standalone-auth/m.log", "journal": true, "port": 2200, "setParameter": {"enableTestCommands": 1} } } mongodb-1.1.5/scripts/presets/standalone-plain.json0000664000175000017500000000074612673034026022315 0ustar jmikolajmikola{ "name": "mongod", "id" : "STANDALONE_PLAIN", "auth_key": "secret", "login": "root", "password": "toor", "procParams": { "dbpath": "/tmp/standalone-plain/", "ipv6": true, "logappend": true, "logpath": "/tmp/standalone-plain/m.log", "journal": true, "port": 2400, "setParameter": {"enableTestCommands": 1, "saslauthdPath": "/var/run/saslauthd/mux", "authenticationMechanisms": "MONGODB-CR,PLAIN"} } } mongodb-1.1.5/scripts/presets/standalone-ssl.json0000664000175000017500000000101512673034026022001 0ustar jmikolajmikola{ "name": "mongod", "id" : "STANDALONE_SSL", "procParams": { "dbpath": "/tmp/standalone-ssl/", "ipv6": true, "logappend": true, "logpath": "/tmp/standalone-ssl/m.log", "journal": true, "port": 2100, "setParameter": {"enableTestCommands": 1} }, "sslParams": { "sslMode": "requireSSL", "sslCAFile": "/phongo/scripts/ssl/ca.pem", "sslPEMKeyFile": "/phongo/scripts/ssl/server.pem", "sslWeakCertificateValidation": true } } mongodb-1.1.5/scripts/presets/standalone-x509.json0000664000175000017500000000125612673034026021714 0ustar jmikolajmikola{ "name": "mongod", "id" : "STANDALONE_X509", "authSource": "$external", "login": "C=US,ST=New York,L=New York City,O=MongoDB,OU=KernelUser,CN=client", "procParams": { "dbpath": "/tmp/standalone-x509/", "ipv6": true, "logappend": true, "logpath": "/tmp/standalone-x509/m.log", "journal": true, "port": 2300, "setParameter": {"enableTestCommands": 1, "authenticationMechanisms": "MONGODB-X509"} }, "sslParams": { "sslMode": "requireSSL", "sslCAFile": "/phongo/scripts/ssl/ca.pem", "sslPEMKeyFile": "/phongo/scripts/ssl/server.pem", "sslWeakCertificateValidation": true } } mongodb-1.1.5/scripts/presets/standalone.json0000664000175000017500000000046712673034026021214 0ustar jmikolajmikola{ "name": "mongod", "id" : "STANDALONE", "procParams": { "dbpath": "/tmp/standalone/", "ipv6": true, "logappend": true, "logpath": "/tmp/standalone/mongod.log", "journal": true, "port": 2000, "setParameter": {"enableTestCommands": 1} } } mongodb-1.1.5/scripts/ssl/ca.pem0000664000175000017500000000564112673034026016372 0ustar jmikolajmikola-----BEGIN CERTIFICATE----- MIIDczCCAlugAwIBAgIBATANBgkqhkiG9w0BAQUFADB0MRcwFQYDVQQDEw5LZXJu ZWwgVGVzdCBDQTEPMA0GA1UECxMGS2VybmVsMRAwDgYDVQQKEwdNb25nb0RCMRYw FAYDVQQHEw1OZXcgWW9yayBDaXR5MREwDwYDVQQIEwhOZXcgWW9yazELMAkGA1UE BhMCVVMwHhcNMTQwNzE3MTYwMDAwWhcNMjAwNzE3MTYwMDAwWjB0MRcwFQYDVQQD Ew5LZXJuZWwgVGVzdCBDQTEPMA0GA1UECxMGS2VybmVsMRAwDgYDVQQKEwdNb25n b0RCMRYwFAYDVQQHEw1OZXcgWW9yayBDaXR5MREwDwYDVQQIEwhOZXcgWW9yazEL MAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCBxSXj qA5y2EMQkcmvLDNikE88Og3+spJ3ex60HWVPk8EeXN68jyfbKLYsoCcBE2rBAE/N shVBJa8irh0o/UTh1XNW4iGCsfMvYamXiHnaOjmGVKjfBoj6pzQH0uK0X5olm3Sa zZPkLLCR81yxsK6woJZMFTvrlEjxj/SmDZ9tVXW692bC4i6nGvOCSpgv9kms85xO Ed2xbuCLXFDXKafXZd5AK+iegkDs3ah7VXMEE8sbqGnlqC1nsy5bpCnb7aC+3af7 SV2XEFlSQT5kwTmk9CvTDzM9O78SO8nNhEOFBLQEdGDGd3BShE8dCdh2JTy3zKsb WeE+mxy0mEwxNfGfAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEF BQADggEBAANwbvhM5K/Jcl6yzUSqAawvyAypT5aWBob7rt9KFq/aemjMN0gY2nsS 8WTGd9jiXlxGc/TzrK6MOsJ904UAFE1L9uR//G1gIBa9dNbYoiii2Fc8b1xDVJEP b23rl/+GAT6UTSY+YgEjeA4Jk6H9zotO07lSw06rbCQam5SdA5UiMvuLHWCo3BHY 8WzqLiW/uHlb4K5prF9yuTUBEIgkRvvvyOKXlRvm1Ed5UopT2hmwA86mffAfgJc2 vSbm9/8Q00fYwO7mluB6mbEcnbquaqRLoB83k+WbwUAZ2yjWHXuXVMPwyaysazcp nOjaLwQJQgKejY62PiNcw7xC/nIxBeI= -----END CERTIFICATE----- -----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEAgcUl46gOcthDEJHJrywzYpBPPDoN/rKSd3setB1lT5PBHlze vI8n2yi2LKAnARNqwQBPzbIVQSWvIq4dKP1E4dVzVuIhgrHzL2Gpl4h52jo5hlSo 3waI+qc0B9LitF+aJZt0ms2T5CywkfNcsbCusKCWTBU765RI8Y/0pg2fbVV1uvdm wuIupxrzgkqYL/ZJrPOcThHdsW7gi1xQ1ymn12XeQCvonoJA7N2oe1VzBBPLG6hp 5agtZ7MuW6Qp2+2gvt2n+0ldlxBZUkE+ZME5pPQr0w8zPTu/EjvJzYRDhQS0BHRg xndwUoRPHQnYdiU8t8yrG1nhPpsctJhMMTXxnwIDAQABAoIBAD5iGOnM800wO2Uu wGbOd9FNEFoiinHDRHfdnw/1BavwmqjO+mBo7T8E3jarsrRosiwfyz1V+7O6uuuQ CgKXZlKuOuksgfGDPCWt7EolWHaZAOhbsGaujJD6ah/MuCD/yGmFxtNYOl05QpSX Cht9lSzhtf7TQl/og/xkOLbO27JB540ck/OCSOczXg9Z/O8AmIUyDn7AKb6G1Zhk 2IN//HQoAvDUMZLWrzy+L7YGbA8pBR3yiPsYBH0rX2Oc9INpiGA+B9Nf1HDDsxeZ /o+5xLbRDDfIDtlYO0cekJ053W0zUQLrMEIn9991EpG2O/fPgs10NlKJtaFH8CmT ExgVA9ECgYEA+6AjtUdxZ0BL3Wk773nmhesNH5/5unWFaGgWpMEaEM7Ou7i6QApL KAbzOYItV3NNCbkcrejq7jsDGEmiwUOdXeQx6XN7/Gb2Byc/wezy5ALi0kcUwaur 6s9+Ah+T4vcU2AjfuCWXIpe46KLEbwORmCRQGwkCBCwRhHGt5sGGxTkCgYEAhAaw voHI6Cb+4z3PNAKRnf2rExBYRyCz1KF16ksuwJyQSLzFleXRyRWFUEwLuVRL0+EZ JXhMbtrILrc23dJGEsB8kOCFehSH/IuL5eB0QfKpDFA+e6pimsbVeggx/rZhcERB WkcV3jN4O82gSL3EnIgvAT1/nwhmbmjvDhFJhZcCgYBaW4E3IbaZaz9S/O0m69Fa GbQWvS3CRV1oxqgK9cTUcE9Qnd9UC949O3GwHw0FMERjz3N7B/8FGW/dEuQ9Hniu NLmvqWbGlnqWywNcMihutJKbDCdp/Km5olUPkiNbB3sWsOkViXoiU/V0pK6BZvir d67EZpGwydpogyH9kVVCEQKBgGHXc3Q7SmCBRbOyQrQQk0m6i+V8328W1S5m2bPg M62aWXMOMn976ZRT1pBDSwz1Y5yJ3NDf7gTZLjEwpgCNrFCJRcc4HLL0NDL8V5js VjvpUU5GyYdsJdb+M4ZUPHi/QEaqzqPQumwJSLlJEdfWirZWVj9dDA8XcpGwQjjy psHRAoGBAJUTgeJYhjK7k5sgfh+PRqiRJP0msIH8FK7SenBGRUkelWrW6td2Riey EcOCMFkRWBeDgnZN5xDyWLBgrzpw9iHQQIUyyBaFknQcRUYKHkCx+k+fr0KHHCUb X2Kvf0rbeMucb4y/h7950HkBBq83AYKMAoI8Ql3cx7pKmyOLXRov -----END RSA PRIVATE KEY-----mongodb-1.1.5/scripts/ssl/client.pem0000664000175000017500000000561112673034026017262 0ustar jmikolajmikola-----BEGIN CERTIFICATE----- MIIDXTCCAkWgAwIBAgIBAzANBgkqhkiG9w0BAQUFADB0MRcwFQYDVQQDEw5LZXJu ZWwgVGVzdCBDQTEPMA0GA1UECxMGS2VybmVsMRAwDgYDVQQKEwdNb25nb0RCMRYw FAYDVQQHEw1OZXcgWW9yayBDaXR5MREwDwYDVQQIEwhOZXcgWW9yazELMAkGA1UE BhMCVVMwHhcNMTQwNzE3MTYwMDAwWhcNMjAwNzE3MTYwMDAwWjBwMQ8wDQYDVQQD EwZjbGllbnQxEzARBgNVBAsTCktlcm5lbFVzZXIxEDAOBgNVBAoTB01vbmdvREIx FjAUBgNVBAcTDU5ldyBZb3JrIENpdHkxETAPBgNVBAgTCE5ldyBZb3JrMQswCQYD VQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJIFboAk9Fdi DY5Xld2iw36vB3IpHEfgWIimd+l1HX4jyp35i6xoqkZZHJUL/NMbUFJ6+44EfFJ5 biB1y1Twr6GqpYp/3R30jKQU4PowO7DSal38MR34yiRFYPG4ZPPXXfwPSuwKrSNo bjqa0/DRJRVQlnGwzJkPsWxIgCjc8KNO/dSHv/CGymc9TjiFAI0VVOhMok1CBNvc ifwWjGBg5V1s3ItMw9x5qk+b9ff5hiOAGxPiCrr8R0C7RoeXg7ZG8K/TqXbsOZEG AOQPRGcrmqG3t4RNBJpZugarPWW6lr11zMpiPLFTrbq3ZNYB9akdsps4R43TKI4J AOtGMJmK430CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAA+nPgVT4addi13yB6mjW +UhdUkFwtb1Wcg0sLtnNucopHZLlCj5FfDdp1RQxe3CyMonxyHTKkrWtQmVtUyvf C/fjpIKt9A9kAmveMHBiu9FTNTc0sbiXcrEBeHF5cD7N+Uwfoc/4rJm0WjEGNkAd pYLCCLVZXPVr3bnc3ZLY1dFZPsJrdH3nJGMjLgUmoNsKnaGozcjiKiXqm6doFzkg 0Le5yD4C/QTaie2ycFa1X5bJfrgoMP7NqKko05h4l0B0+DnjpoTJN+zRreNTMKvE ETGvpUu0IYGxe8ZVAFnlEO/lUeMrPFvH+nDmJYsxO1Sjpds2hi1M1JoeyrTQPwXj 2Q== -----END CERTIFICATE----- -----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEAkgVugCT0V2INjleV3aLDfq8HcikcR+BYiKZ36XUdfiPKnfmL rGiqRlkclQv80xtQUnr7jgR8UnluIHXLVPCvoaqlin/dHfSMpBTg+jA7sNJqXfwx HfjKJEVg8bhk89dd/A9K7AqtI2huOprT8NElFVCWcbDMmQ+xbEiAKNzwo0791Ie/ 8IbKZz1OOIUAjRVU6EyiTUIE29yJ/BaMYGDlXWzci0zD3HmqT5v19/mGI4AbE+IK uvxHQLtGh5eDtkbwr9Opduw5kQYA5A9EZyuaobe3hE0Emlm6Bqs9ZbqWvXXMymI8 sVOturdk1gH1qR2ymzhHjdMojgkA60YwmYrjfQIDAQABAoIBAB249VEoNIRE9TVw JpVCuEBlKELYk2UeCWdnWykuKZ6vcmLNlNy3QVGoeeTs172w5ZykY+f4icXP6da5 o3XauCVUMvYKKNwcFzSe+1xxzPSlH/mZh/Xt2left6f8PLBVuk/AXSPG2I9Ihodv VIzERaQdD0J9FmhhhV/hMhUfQ+w5rTCaDpq1KVGU61ks+JAtlQ46g+cvPF9c80cI TEC875n2LqWKmLRN43JUnctV3uGTmolIqCRMHPAs/egl+lG2RXJjqXSQ2uFLOvC/ PXtBb597yadSs2BWPnTu/r7LbLGBAExzlQK1uFsTvuKsBPb3qrvUux0L68qwPuiv W24N8BECgYEAydtAvVB7OymQEX3mck2j7ixDN01wc1ZaCLBDvYPYS/Pvzq4MBiAD lHRtbIa6HPGA5jskbccPqQn8WGnJWCaYvCQryvgaA+BBgo1UTLfQJUo/7N5517vv KvbUa6NF0nj3VwfDV1vvy+amoWi9NOVn6qOh0K84PF4gwagb1EVy9MsCgYEAuTAt KCWdZ/aNcKgJc4NCUqBpLPF7EQypX14teixrbF/IRNS1YC9S20hpkG25HMBXjpBe tVg/MJe8R8CKzYjCt3z5Ff1bUQ2bzivbAtgjcaO0Groo8WWjnamQlrIQcvWM7vBf dnIflQ0slxbHfCi3XEe8tj2T69R7wJZ8L7PxR9cCgYEACgwNtt6Qo6s37obzt3DB 3hL57YC/Ph5oMNKFLKOpWm5z2zeyhYOGahc5cxNppBMpNUxwTb6AuwsyMjxhty+E nqi2PU4IDXVWDWd3cLIdfB2r/OA99Ez4ZI0QmaLw0L8QoJZUVL7QurdqR9JsyHs6 puUqIrb195s/yiPR7sjeJe0CgYEAuJviKEd3JxCN52RcJ58OGrh2oKsJ9/EbV0rX Ixfs7th9GMDDHuOOQbNqKOR4yMSlhCU/hKA4PgTFWPIEbOiM08XtuZIb2i0qyNjH N4qnqr166bny3tJnzOAgl1ljNHa8y+UsBTO3cCr17Jh0vL0KLSAGa9XvBAWKaG6b 1iIXwXkCgYAVz+DA1yy0qfXdS1pgPiCJGlGZXpbBcFnqvbpGSclKWyUG4obYCbrb p5VKVfoK7uU0ly60w9+PNIRsX/VN/6SVcoOzKx40qQBMuYfJ72DQrsPjPYvNg/Nb 4SK94Qhp9TlAyXbqKJ02DjtuDim44sGZ8g7b+k3FfoK4OtzNsqdVdQ== -----END RSA PRIVATE KEY-----mongodb-1.1.5/scripts/ssl/crl.pem0000664000175000017500000000376512673034026016574 0ustar jmikolajmikolaCertificate Revocation List (CRL): Version 2 (0x1) Signature Algorithm: sha256WithRSAEncryption Issuer: /CN=Kernel Test CA/OU=Kernel/O=MongoDB/L=New York City/ST=New York/C=US Last Update: Aug 21 13:56:28 2014 GMT Next Update: Aug 18 13:56:28 2024 GMT CRL extensions: X509v3 CRL Number: 4096 No Revoked Certificates. Signature Algorithm: sha256WithRSAEncryption 48:1b:0b:b1:89:f5:6f:af:3c:dd:2a:a0:e5:55:04:80:16:b4: 23:98:39:bb:9f:16:c9:25:73:72:c6:a6:73:21:1d:1a:b6:99: fc:47:5e:bc:af:64:29:02:9c:a5:db:15:8a:65:48:3c:4f:a6: cd:35:47:aa:c6:c0:39:f5:a6:88:8f:1b:6c:26:61:4e:10:d7: e2:b0:20:3a:64:92:c1:d3:2a:11:3e:03:e2:50:fd:4e:3c:de: e2:e5:78:dc:8e:07:a5:69:55:13:2b:8f:ae:21:00:42:85:ff: b6:b1:2b:69:08:40:5a:25:8c:fe:57:7f:b1:06:b0:72:ff:61: de:21:59:05:a8:1b:9e:c7:8a:08:ab:f5:bc:51:b3:36:68:0f: 54:65:3c:8d:b7:80:d0:27:01:3e:43:97:89:19:89:0e:c5:01: 2c:55:9f:b6:e4:c8:0b:35:f8:52:45:d3:b4:09:ce:df:73:98: f5:4c:e4:5a:06:ac:63:4c:f8:4d:9c:af:88:fc:19:f7:77:ea: ee:56:18:49:16:ce:62:66:d1:1b:8d:66:33:b5:dc:b1:25:b3: 6c:81:e9:d0:8a:1d:83:61:49:0e:d9:94:6a:46:80:41:d6:b6: 59:a9:30:55:3d:5b:d3:5b:f1:37:ec:2b:76:d0:3a:ac:b2:c8: 7c:77:04:78 -----BEGIN X509 CRL----- MIIBzjCBtwIBATANBgkqhkiG9w0BAQsFADB0MRcwFQYDVQQDEw5LZXJuZWwgVGVz dCBDQTEPMA0GA1UECxMGS2VybmVsMRAwDgYDVQQKEwdNb25nb0RCMRYwFAYDVQQH Ew1OZXcgWW9yayBDaXR5MREwDwYDVQQIEwhOZXcgWW9yazELMAkGA1UEBhMCVVMX DTE0MDgyMTEzNTYyOFoXDTI0MDgxODEzNTYyOFqgDzANMAsGA1UdFAQEAgIQADAN BgkqhkiG9w0BAQsFAAOCAQEASBsLsYn1b6883Sqg5VUEgBa0I5g5u58WySVzcsam cyEdGraZ/EdevK9kKQKcpdsVimVIPE+mzTVHqsbAOfWmiI8bbCZhThDX4rAgOmSS wdMqET4D4lD9Tjze4uV43I4HpWlVEyuPriEAQoX/trEraQhAWiWM/ld/sQawcv9h 3iFZBagbnseKCKv1vFGzNmgPVGU8jbeA0CcBPkOXiRmJDsUBLFWftuTICzX4UkXT tAnO33OY9UzkWgasY0z4TZyviPwZ93fq7lYYSRbOYmbRG41mM7XcsSWzbIHp0Iod g2FJDtmUakaAQda2WakwVT1b01vxN+wrdtA6rLLIfHcEeA== -----END X509 CRL----- mongodb-1.1.5/scripts/ssl/server.pem0000664000175000017500000000566512673034026017323 0ustar jmikolajmikola-----BEGIN CERTIFICATE----- MIIDfjCCAmagAwIBAgIBBzANBgkqhkiG9w0BAQUFADB0MRcwFQYDVQQDEw5LZXJu ZWwgVGVzdCBDQTEPMA0GA1UECxMGS2VybmVsMRAwDgYDVQQKEwdNb25nb0RCMRYw FAYDVQQHEw1OZXcgWW9yayBDaXR5MREwDwYDVQQIEwhOZXcgWW9yazELMAkGA1UE BhMCVVMwHhcNMTQwNzE3MTYwMDAwWhcNMjAwNzE3MTYwMDAwWjBsMQ8wDQYDVQQD EwZzZXJ2ZXIxDzANBgNVBAsTBktlcm5lbDEQMA4GA1UEChMHTW9uZ29EQjEWMBQG A1UEBxMNTmV3IFlvcmsgQ2l0eTERMA8GA1UECBMITmV3IFlvcmsxCzAJBgNVBAYT AlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp76KJeDczBqjSPJj 5f8DHdtrWpQDK9AWNDlslWpi6+pL8hMqwbX0D7hC2r3kAgccMyFoNIudPqIXfXVd 1LOh6vyY+jveRvqjKW/UZVzZeiL4Gy4bhke6R8JRC3O5aMKIAbaiQUAI1Nd8LxIt LGvH+ia/DFza1whgB8ym/uzVQB6igOifJ1qHWJbTtIhDKaW8gvjOhv5R3jzjfLEb R9r5Q0ZyE0lrO27kTkqgBnHKPmu54GSzU/r0HM3B+Sc/6UN+xNhNbuR+LZ+EvJHm r4de8jhW8wivmjTIvte33jlLibQ5nYIHrlpDLEwlzvDGaIio+OfWcgs2WuPk98MU tht0IQIDAQABoyMwITAfBgNVHREEGDAWgglsb2NhbGhvc3SCCTEyNy4wLjAuMTAN BgkqhkiG9w0BAQUFAAOCAQEANoYxvVFsIol09BQA0fwryAye/Z4dYItvKhmwB9VS t99DsmJcyx0P5meB3Ed8SnwkD0NGCm5TkUY/YLacPP9uJ4SkbPkNZ1fRISyShCCn SGgQUJWHbCbcIEj+vssFb91c5RFJbvnenDkQokRvD2VJWspwioeLzuwtARUoMH3Y qg0k0Mn7Bx1bW1Y6xQJHeVlnZtzxfeueoFO55ZRkZ0ceAD/q7q1ohTXi0vMydYgu 1CB6VkDuibGlv56NdjbttPJm2iQoPaez8tZGpBo76N/Z1ydan0ow2pVjDXVOR84Y 2HSZgbHOGBiycNw2W3vfw7uK0OmiPRTFpJCmewDjYwZ/6w== -----END CERTIFICATE----- -----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEAp76KJeDczBqjSPJj5f8DHdtrWpQDK9AWNDlslWpi6+pL8hMq wbX0D7hC2r3kAgccMyFoNIudPqIXfXVd1LOh6vyY+jveRvqjKW/UZVzZeiL4Gy4b hke6R8JRC3O5aMKIAbaiQUAI1Nd8LxItLGvH+ia/DFza1whgB8ym/uzVQB6igOif J1qHWJbTtIhDKaW8gvjOhv5R3jzjfLEbR9r5Q0ZyE0lrO27kTkqgBnHKPmu54GSz U/r0HM3B+Sc/6UN+xNhNbuR+LZ+EvJHmr4de8jhW8wivmjTIvte33jlLibQ5nYIH rlpDLEwlzvDGaIio+OfWcgs2WuPk98MUtht0IQIDAQABAoIBACgi1ilECXCouwMc RDzm7Jb7Rk+Q9MVJ79YlG08Q+oRaNjvAzE03PSN5wj1WjDTUALJXPvi7oy82V4qE R6Q6Kvbv46aUJpYzKFEk2dw7ACpSLa1LNfjGNtMusnecA/QF/8bxLReRu8s5mBQn NDnZvCqllLbfjNlAvsF+/UIn5sqFZpAZPMtPwkTAeh5ge8H9JvrG8y8aXsiFGAhV Z7tMZyn8wPCUrRi14NLvVB4hxM66G/tuTp8r9AmeTU+PV+qbCnKXd+v0IS52hvX9 z75OPfAc66nm4bbPCapb6Yx7WaewPXXU0HDxeaT0BeQ/YfoNa5OT+ZOX1KndSfHa VhtmEsECgYEA3m86yYMsNOo+dkhqctNVRw2N+8gTO28GmWxNV9AC+fy1epW9+FNR yTQXpBkRrR7qrd5mF7WBc7vAIiSfVs021RMofzn5B1x7jzkH34VZtlviNdE3TZhx lPinqo0Yy3UEksgsCBJFIofuCmeTLk4ZtqoiZnXr35RYibaZoQdUT4kCgYEAwQ6Y xsKFYFks1+HYl29kR0qUkXFlVbKOhQIlj/dPm0JjZ0xYkUxmzoXD68HrOWgz7hc2 hZaQTgWf+8cRaZNfh7oL+Iglczc2UXuwuUYguYssD/G6/ZPY15PhItgCghaU5Ewy hMwIJ81NENY2EQTgk/Z1KZitXdVJfHl/IPMQgdkCgYASdqkqkPjaa5dDuj8byO8L NtTSUYlHJbAmjBbfcyTMG230/vkF4+SmDuznci1FcYuJYyyWSzqzoKISM3gGfIJQ rYZvCSDiu4qGGPXOWANaX8YnMXalukGzW/CO96dXPB9lD7iX8uxKMX5Q3sgYz+LS hszUNHWf2XB//ehCtZkKAQKBgQCxL2luepeZHx82H9T+38BkYgHLHw0HQzLkxlyd LjlE4QCEjSB4cmukvkZbuYXfEVEgAvQKVW6p/SWhGkpT4Gt8EXftKV9dyF21GVXQ JZnhUOcm1xBsrWYGLXYi2agrpvgONBTlprERfq5tdnz2z8giZL+RZswu45Nnh8bz AcKzuQKBgQCGOQvKvNL5XKKmws/KRkfJbXgsyRT2ubO6pVL9jGQG5wntkeIRaEpT oxFtWMdPx3b3cxtgSP2ojllEiISk87SFIN1zEhHZy/JpTF0GlU1qg3VIaA78M1p2 ZdpUsuqJzYmc3dDbQMepIaqdW4xMoTtZFyenUJyoezz6eWy/NlZ/XQ== -----END RSA PRIVATE KEY-----mongodb-1.1.5/scripts/ubuntu/ldap/install.sh0000664000175000017500000000100612673034026020736 0ustar jmikolajmikolasudo apt-get -y install ldap-utils libsasl2-modules-ldap sasl2-bin # setup saslauthd sudo sed -i 's/MECHANISMS="pam"/MECHANISMS="ldap"/' /etc/default/saslauthd sudo sed -i 's/START=no/START="yes"/' /etc/default/saslauthd sudo cp /phongo/scripts/ubuntu/ldap/saslauthd.conf /etc/ sudo service saslauthd restart testsaslauthd -u bugs -p password -s mongod -f /var/run/saslauthd/mux #ldapsearch -x -LLL -b dc=10gen,dc=me -h 192.168.112.20 #ldapsearch -x -b '' -s base '(objectclass=*)' namingContexts -h 192.168.112.20 mongodb-1.1.5/scripts/ubuntu/ldap/saslauthd.conf0000664000175000017500000000015012673034026021572 0ustar jmikolajmikolaldap_servers: ldap://192.168.112.20:389 ldap_search_base: ou=Users,dc=10gen,dc=me ldap_filter: (uid=%u) mongodb-1.1.5/scripts/ubuntu/essentials.sh0000664000175000017500000000036512673034026020531 0ustar jmikolajmikolaif [ ! -e ".provisioned" ]; then # Tools you can't live without apt-get update apt-get install -y build-essential git vim libtool autoconf # I can't stand emacs echo 'set -o vi' | sudo tee /etc/profile.d/vishell.sh touch .provisioned fi mongodb-1.1.5/scripts/ubuntu/mongo-orchestration.sh0000664000175000017500000000327712673034026022365 0ustar jmikolajmikola# Enable MongoDB Enterprise repo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10 # 3.2 key apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv EA312927 echo 'deb http://repo.mongodb.com/apt/ubuntu precise/mongodb-enterprise/3.2 multiverse' | sudo tee /etc/apt/sources.list.d/mongodb-enterprise-3.2.list echo 'deb http://repo.mongodb.com/apt/ubuntu precise/mongodb-enterprise/3.0 multiverse' | sudo tee /etc/apt/sources.list.d/mongodb-enterprise-3.0.list echo 'deb http://repo.mongodb.com/apt/ubuntu precise/mongodb-enterprise/2.6 multiverse' | sudo tee /etc/apt/sources.list.d/mongodb-enterprise-2.6.list echo 'deb http://repo.mongodb.com/apt/ubuntu precise/mongodb-enterprise/2.4 multiverse' | sudo tee /etc/apt/sources.list.d/mongodb-enterprise-2.4.list apt-get update apt-get install -y libsnmp15 libgsasl7 sudo apt-get download mongodb-enterprise-server=3.2.0 sudo apt-get download mongodb-enterprise-mongos=3.2.0 sudo apt-get download mongodb-enterprise-server=3.0.3 sudo apt-get download mongodb-enterprise-server=2.6.9 sudo apt-get download mongodb-10gen-enterprise=2.4.13 dpkg -x mongodb-10gen-enterprise_2.4.13_amd64.deb 2.4.13 dpkg -x mongodb-enterprise-server_2.6.9_amd64.deb 2.6.9 dpkg -x mongodb-enterprise-server_3.0.3_amd64.deb 3.0.3 dpkg -x mongodb-enterprise-server_3.2.0_amd64.deb 3.2.0 dpkg -x mongodb-enterprise-mongos_3.2.0_amd64.deb 3.2.0 # Python stuff for mongo-orchestration apt-get install -y python python-dev python-pip pip install --upgrade 'git+https://github.com/10gen/mongo-orchestration.git#egg=mongo_orchestration' # Launch mongo-orchestration mongo-orchestration -f mongo-orchestration-config.json -b 192.168.112.10 --enable-majority-read-concern start mongodb-1.1.5/scripts/ubuntu/phongo.sh0000664000175000017500000000056612673034026017654 0ustar jmikolajmikolaapt-get install -y php-pear php5-dbg gdb apt-get install -y libssl-dev libsasl2-dev libpcre3-dev pkg-config ls -1 /phongo/mongodb*.tgz | sort -n -r | xargs sudo pecl install -f 2>&1 > /phongo/.build php -m | grep -q mongodb || echo "extension=mongodb.so" >> `php --ini | grep "Loaded Configuration" | sed -e "s|.*:\s*||"` pecl run-tests -q -p mongodb 2>&1 > /phongo/.tests mongodb-1.1.5/scripts/vmware/kernel.sh0000664000175000017500000000046612673034026017620 0ustar jmikolajmikola# Ensure that VMWare Tools recompiles kernel modules # when we update the linux images sed -i.bak 's/answer AUTO_KMODS_ENABLED_ANSWER no/answer AUTO_KMODS_ENABLED_ANSWER yes/g' /etc/vmware-tools/locations sed -i.bak 's/answer AUTO_KMODS_ENABLED no/answer AUTO_KMODS_ENABLED yes/g' /etc/vmware-tools/locations mongodb-1.1.5/scripts/convert-mo-tests.php0000664000175000017500000002130512673034026020440 0ustar jmikolajmikola --FILE-- array( "method" => "DELETE", "timeout" => 60, "header" => "Accept: application/json\r\n" . "Content-type: application/x-www-form-urlencoded", "ignore_errors" => true, ), ); $context = stream_context_create($opts); $out = file_get_contents($url, false, $context); } function mo_post($url, $body) { global $KILLLIST; $url = getMOUri() . $url; $opts = array("http" => array( "method" => "POST", "timeout" => 60, "header" => "Accept: application/json\r\n" . "Content-type: application/x-www-form-urlencoded", "content" => json_encode($body), "ignore_errors" => true, ), ); $context = stream_context_create($opts); $out = file_get_contents($url, false, $context); $array = json_decode($out, true); if ($array && !empty($array["mongodb_uri"])) { $KILLLIST[] = $array["id"]; return $array["mongodb_uri"]; } } $KILLLIST = array(); $INITCONFIG = %INITCONFIG%; $dsn = "%DSN%"; if ($INITCONFIG) { $dsn = mo_post("/%URLTYPE%", $INITCONFIG); } $manager = new MongoDB\Driver\Manager($dsn); %TESTPLAN%; foreach($KILLLIST as $id) { mo_delete("/%URLTYPE%/$id"); } ?> ===DONE=== --EXPECTF-- %OUTPUT% ===DONE=== TEMPLATE; ?>getMessage() . "\n"; } file_put_contents($phptfile, $phpt); } function convert($test, $template) { $TESTPLAN = array(); $OUTPUT = ""; $test["phases"] = isset($test["phases"]) ? $test["phases"] : array(); foreach($test["phases"] as $phase) { $TESTPLAN[] = phase($phase, $output); if ($output) { ob_start(); var_dump($output); $OUTPUT .= ob_get_contents(); ob_end_clean(); $OUTPUT = str_replace('2) "%s"', '%d) "%s"', $OUTPUT); } } foreach($test["tests"] as $phase) { $TESTPLAN[] = phase($phase, $output); if ($output) { ob_start(); var_dump($output); $OUTPUT .= ob_get_contents(); ob_end_clean(); $OUTPUT = str_replace('2) "%s"', '%d) "%s"', $OUTPUT); } } $replacements = array( "%DSN%" => clientSetup($test), "%DESCRIPTION%" => description($test), "%INITCONFIG%" => initConfig($test), "%URLTYPE%" => $test["type"], "%TESTPLAN%" => join("\n\n", $TESTPLAN), "%OUTPUT%" => rtrim($OUTPUT), ); return makeTest($replacements, $template); } function phase($phase, &$output) { $output = null; if (isset($phase["MOOperation"])) { return MOOperation($phase["MOOperation"], $output); } if (isset($phase["clientHosts"])) { return clientHosts($phase["clientHosts"], $output); } if (isset($phase["clientOperation"])) { return clientOperation($phase["clientOperation"], $output); } if (isset($phase["wait"])) { return 'sleep(' . $phase["wait"] . ');'; } throw new UnexpectedValueException("Don't know how to deal with " . json_encode($phase)); } function MOOperation($phase, &$output) { $method = strtolower($phase["method"]); switch($method) { case "post": return 'mo_post("' . $phase["uri"] . '", ' . var_export($phase["payload"], true) . ');'; case "delete": return 'mo_delete("' . $phase["uri"] . '");'; default: throw new UnexpectedValueException("Don't know the method $method"); } } function clientHosts($hosts, &$output) { $output = array(); $retval = <<< CODE \$clientHosts = array(); CODE; if (!empty($hosts['primary'])) { $primary = var_export($hosts['primary'], true); $retval .= <<< CODE \$found = array_filter(\$manager->getServers(), function(\$server) { return \$server->getHost() == $primary && \$server->getType() == MongoDB\\Driver\\SERVERTYPE_RS_PRIMARY; }); if (count(\$found) == 1) { \$clientHosts['primary'] = $primary; } CODE; $output['primary'] = $hosts['primary']; } if (!empty($hosts['secondaries'])) { foreach ($hosts['secondaries'] as $secondaryHost) { $secondary = var_export($secondaryHost, true); $retval .= <<< CODE \$found = array_filter(\$manager->getServers(), function(\$server) { return \$server->getHost() == $secondary && \$server->getType() == MongoDB\\Driver\\SERVERTYPE_RS_SECONDARY; }); if (count(\$found) == 1) { \$clientHosts['secondaries'][] = $secondary; } CODE; $output['secondaries'][] = $secondaryHost; } } $retval .= <<< CODE var_dump(\$clientHosts); CODE; return $retval; } function clientOperation($phase, &$output) { switch($phase["operation"]) { case "insertOne": $output = !isset($phase["outcome"]) ? array("ok" => 1) : $phase["outcome"]; if (!$output["ok"]) { $output["errmsg"] = "%s"; } $wc = !isset($phase["writeConcern"]) ? 1 : $phase["writeConcern"]["w"]; $doc = var_export($phase["doc"], true);; $doc = str_replace("\n", "\n ", $doc); $retval = <<< CODE try { \$wc = new MongoDB\\Driver\\WriteConcern($wc); \$bulk = new MongoDB\Driver\BulkWrite(); \$bulk->insert($doc); \$result = \$manager->executeBulkWrite("databaseName.collectionName", \$bulk, \$wc); if (\$result->getInsertedCount() == 1) { var_dump(array("ok" => 1)); } else { var_dump(array("ok" => 0, "errmsg" => "getInsertedCount => " . \$result->getInsertedCount())); } } catch(Exception \$e) { var_dump(array("ok" => 0, "errmsg" => get_class(\$e) . ": " . \$e->getMessage())); } CODE; return $retval; break; case "find": $output = $phase["outcome"]; if (!$output["ok"]) { $output["errmsg"] = "%s"; } $retval = <<< CODE try { \$query = new MongoDB\\Driver\\Query(array()); \$result = \$manager->executeQuery("databaseName.collectionName", \$query)->toArray(); var_dump(array("ok" => 1)); } catch(Exception \$e) { var_dump(array("ok" => 0, "errmsg" => get_class(\$e) . ": " . \$e->getMessage())); } CODE; return $retval; break; default: throw new UnexpectedValueException("IDK what to do about {$phase["operation"]}"); } } function clientSetUp($test) { $setup = $test["clientSetUp"]; if (!$setup) { throw new UnexpectedValueException("No 'clientSetUp' key provided"); } $seedlist = join(",", $setup["hosts"]); $options = array(); if (!empty($setup["options"])) { $entries = array(); foreach($setup["options"] as $k => $v) { switch($k) { case "readPreference": $entries[] = "$k={$v["mode"]}"; break; case "heartbeatFrequency": $entries[] = "$k=$v"; break; default: throw new Exception("Don't know how to handle '$k'"); } } $options = join("&", $entries); } if ($options) { return sprintf("mongodb://%s/?%s", $seedlist, $options); } else { return sprintf("mongodb://%s", $seedlist); } } function makeTest($replacements, $template) { return str_replace(array_keys($replacements), array_values($replacements), $template); } function description($test) { static $count = 0; $desc = $test["description"]; return sprintf("Cluster Integration Test#%03d: %s", ++$count, $desc); } function initConfig($test) { // The initConfig entry alone isn't valid MO post $config = $test["initConfig"]; $config["name"] = "mongod"; return var_export($config, true); } mongodb-1.1.5/scripts/list-servers.php0000664000175000017500000000034012673034026017645 0ustar jmikolajmikola $uri) { printf("%-20s \t %s\n", $serverid, $uri); } mongodb-1.1.5/scripts/start-servers.php0000664000175000017500000002037012673034026020034 0ustar jmikolajmikola [ "scripts/presets/standalone.json", "scripts/presets/standalone-24.json", "scripts/presets/standalone-26.json", "scripts/presets/standalone-30.json", "scripts/presets/standalone-ssl.json", "scripts/presets/standalone-auth.json", "scripts/presets/standalone-x509.json", "scripts/presets/standalone-plain.json", ], "replicasets" => [ "scripts/presets/replicaset.json", "scripts/presets/replicaset-30.json", ], ]; function make_ctx($preset, $method = "POST") { $opts = [ "http" => [ "timeout" => 60, "method" => $method, "header" => "Accept: application/json\r\n" . "Content-type: application/x-www-form-urlencoded", "content" => json_encode(array("preset" => $preset)), "ignore_errors" => true, ], ]; $ctx = stream_context_create($opts); return $ctx; } function failed($result) { echo "\n\n"; echo join("\n", $result); printf("Last operation took: %.2f secs\n", lap()); exit(); } function mo_http_request($uri, $context) { global $http_response_header; $result = file_get_contents($uri, false, $context); if ($result === false) { failed($http_response_header); } return $result; } printf("Cleaning out previous processes, if any "); lap(); /* Remove all pre-existing ReplicaSets */ $replicasets = mo_http_request(getMOUri() . "/replica_sets", make_ctx(getMOPresetBase(), "GET")); $replicasets = json_decode($replicasets, true); foreach($replicasets["replica_sets"] as $replicaset) { $uri = getMOUri() . "/replica_sets/" . $replicaset["id"]; mo_http_request($uri, make_ctx(getMOPresetBase(), "DELETE")); echo "."; } echo " "; /* Remove all pre-existing servers */ $servers = mo_http_request(getMOUri() . "/servers", make_ctx(getMOPresetBase(), "GET")); $servers = json_decode($servers, true); foreach($servers["servers"] as $server) { $uri = getMOUri() . "/servers/" . $server["id"]; mo_http_request($uri, make_ctx(getMOPresetBase(), "DELETE")); echo "."; } printf("\t(took: %.2f secs)\n", lap()); foreach($PRESETS["standalone"] as $preset) { lap(); $json = json_decode(file_get_contents($preset), true); printf("Starting %-20s ... ", $json["id"]); $result = mo_http_request(getMOUri() . "/servers", make_ctx(getMOPresetBase() . $preset)); $decode = json_decode($result, true); if (!isset($decode["id"])) { failed($decode); } $SERVERS[$decode["id"]] = isset($decode["mongodb_auth_uri"]) ? $decode["mongodb_auth_uri"] : $decode["mongodb_uri"]; printf("'%s'\t(took: %.2f secs)\n", $SERVERS[$decode["id"]], lap()); } echo "---\n"; foreach($PRESETS["replicasets"] as $preset) { lap(); $json = json_decode(file_get_contents($preset), true); printf("Starting %-20s ... ", $json["id"]); $result = mo_http_request(getMOUri() . "/replica_sets", make_ctx(getMOPresetBase() . $preset)); $decode = json_decode($result, true); if (!isset($decode["id"])) { failed($decode); } $SERVERS[$decode["id"]] = isset($decode["mongodb_auth_uri"]) ? $decode["mongodb_auth_uri"] : $decode["mongodb_uri"]; printf("'%s'\t(took: %.2f secs)\n", $SERVERS[$decode["id"]], lap()); } file_put_contents($FILENAME, json_encode($SERVERS, JSON_PRETTY_PRINT)); /* wget --body-data='' --method='GET' --header='Accept: application/json' --header='Content-type: application/x-www-form-urlencoded' http://192.168.112.10:8889/servers wget --body-data='' --method='DELETE' --header='Accept: application/json' --header='Content-type: application/x-www-form-urlencoded' http://192.168.112.10:8889/servers/STANDALONE-AUTH wget --body-data='' --method='DELETE' --header='Accept: application/json' --header='Content-type: application/x-www-form-urlencoded' http://192.168.112.10:8889/servers/STANDALONE wget --body-data='' --method='DELETE' --header='Accept: application/json' --header='Content-type: application/x-www-form-urlencoded' http://192.168.112.10:8889/servers/STANDALONE-24 wget --body-data='' --method='DELETE' --header='Accept: application/json' --header='Content-type: application/x-www-form-urlencoded' http://192.168.112.10:8889/servers/STANDALONE-26 wget --body-data='' --method='DELETE' --header='Accept: application/json' --header='Content-type: application/x-www-form-urlencoded' http://192.168.112.10:8889/servers/RS-two wget --body-data='' --method='DELETE' --header='Accept: application/json' --header='Content-type: application/x-www-form-urlencoded' http://192.168.112.10:8889/servers/RS-arbiter wget --body-data='' --method='DELETE' --header='Accept: application/json' --header='Content-type: application/x-www-form-urlencoded' http://192.168.112.10:8889/servers/STANDALONE-PLAIN wget --body-data='' --method='DELETE' --header='Accept: application/json' --header='Content-type: application/x-www-form-urlencoded' http://192.168.112.10:8889/servers/STANDALONE-X509 wget --body-data='' --method='DELETE' --header='Accept: application/json' --header='Content-type: application/x-www-form-urlencoded' http://192.168.112.10:8889/servers/RS-one wget --body-data='' --method='DELETE' --header='Accept: application/json' --header='Content-type: application/x-www-form-urlencoded' http://192.168.112.10:8889/servers/STANDALONE-SSL wget --body-data='' --method='GET' --header='Accept: application/json' --header='Content-type: application/x-www-form-urlencoded' http://192.168.112.10:8889/replica_sets wget --body-data='' --method='DELETE' --header='Accept: application/json' --header='Content-type: application/x-www-form-urlencoded' http://192.168.112.10:8889/replica_sets/REPLICASET wget --body-data='' --method='GET' --header='Accept: application/json' --header='Content-type: application/x-www-form-urlencoded' http://192.168.112.10:8889/ wget --body-data='' --method='GET' --header='Accept: application/json' --header='Content-type: application/x-www-form-urlencoded' http://192.168.112.10:8889/servers wget --body-data='' --method='GET' --header='Accept: application/json' --header='Content-type: application/x-www-form-urlencoded' http://192.168.112.10:8889/replica_sets wget --body-data='{"preset":"\/phongo\/\/scripts\/presets\/standalone.json"}' --method='POST' --header='Accept: application/json' --header='Content-type: application/x-www-form-urlencoded' http://192.168.112.10:8889/servers wget --body-data='{"preset":"\/phongo\/\/scripts\/presets\/standalone-24.json"}' --method='POST' --header='Accept: application/json' --header='Content-type: application/x-www-form-urlencoded' http://192.168.112.10:8889/servers wget --body-data='{"preset":"\/phongo\/\/scripts\/presets\/standalone-26.json"}' --method='POST' --header='Accept: application/json' --header='Content-type: application/x-www-form-urlencoded' http://192.168.112.10:8889/servers wget --body-data='{"preset":"\/phongo\/\/scripts\/presets\/standalone-ssl.json"}' --method='POST' --header='Accept: application/json' --header='Content-type: application/x-www-form-urlencoded' http://192.168.112.10:8889/servers wget --body-data='{"preset":"\/phongo\/\/scripts\/presets\/standalone-auth.json"}' --method='POST' --header='Accept: application/json' --header='Content-type: application/x-www-form-urlencoded' http://192.168.112.10:8889/servers wget --body-data='{"preset":"\/phongo\/\/scripts\/presets\/standalone-x509.json"}' --method='POST' --header='Accept: application/json' --header='Content-type: application/x-www-form-urlencoded' http://192.168.112.10:8889/servers wget --body-data='{"preset":"\/phongo\/\/scripts\/presets\/standalone-plain.json"}' --method='POST' --header='Accept: application/json' --header='Content-type: application/x-www-form-urlencoded' http://192.168.112.10:8889/servers wget --body-data='{"preset":"\/phongo\/\/scripts\/presets\/replicaset.json"}' --method='POST' --header='Accept: application/json' --header='Content-type: application/x-www-form-urlencoded' http://192.168.112.10:8889/replica_sets */ mongodb-1.1.5/src/BSON/Binary.c0000664000175000017500000001670012673034026015732 0ustar jmikolajmikola/* +---------------------------------------------------------------------------+ | PHP Driver for MongoDB | +---------------------------------------------------------------------------+ | Copyright 2013-2015 MongoDB, Inc. | | | | Licensed under the Apache License, Version 2.0 (the "License"); | | you may not use this file except in compliance with the License. | | You may obtain a copy of the License at | | | | http://www.apache.org/licenses/LICENSE-2.0 | | | | Unless required by applicable law or agreed to in writing, software | | distributed under the License is distributed on an "AS IS" BASIS, | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | See the License for the specific language governing permissions and | | limitations under the License. | +---------------------------------------------------------------------------+ | Copyright (c) 2014-2015 MongoDB, Inc. | +---------------------------------------------------------------------------+ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif /* External libs */ #include #include /* PHP Core stuff */ #include #include #include #include #include /* Our Compatability header */ #include "phongo_compat.h" /* Our stuffz */ #include "php_phongo.h" #include "php_bson.h" PHONGO_API zend_class_entry *php_phongo_binary_ce; zend_object_handlers php_phongo_handler_binary; /* {{{ proto BSON\Binary Binary::__construct(string $data, int $type) Construct a new BSON Binary type */ PHP_METHOD(Binary, __construct) { php_phongo_binary_t *intern; zend_error_handling error_handling; char *data; phongo_zpp_char_len data_len; phongo_long type; zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC); intern = Z_BINARY_OBJ_P(getThis()); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &data, &data_len, &type) == FAILURE) { zend_restore_error_handling(&error_handling TSRMLS_CC); return; } zend_restore_error_handling(&error_handling TSRMLS_CC); if (type < 0 || type > UINT8_MAX) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected type to be an unsigned 8-bit integer, %" PHONGO_LONG_FORMAT " given", type); return; } intern->data = estrndup(data, data_len); intern->data_len = data_len; intern->type = (uint8_t) type; } /* }}} */ /* {{{ proto string Binary::getData() */ PHP_METHOD(Binary, getData) { php_phongo_binary_t *intern; intern = Z_BINARY_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } PHONGO_RETURN_STRINGL(intern->data, intern->data_len); } /* }}} */ /* {{{ proto integer Binary::getType() */ PHP_METHOD(Binary, getType) { php_phongo_binary_t *intern; intern = Z_BINARY_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } RETURN_LONG(intern->type); } /* }}} */ /* {{{ BSON\Binary */ ZEND_BEGIN_ARG_INFO_EX(ai_Binary___construct, 0, 0, 2) ZEND_ARG_INFO(0, data) ZEND_ARG_INFO(0, type) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_Binary_getData, 0, 0, 0) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_Binary_getType, 0, 0, 0) ZEND_END_ARG_INFO(); static zend_function_entry php_phongo_binary_me[] = { PHP_ME(Binary, __construct, ai_Binary___construct, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Binary, getData, ai_Binary_getData, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Binary, getType, ai_Binary_getType, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Manager, __wakeUp, NULL, ZEND_ACC_PUBLIC) PHP_FE_END }; /* }}} */ /* {{{ php_phongo_binary_t object handlers */ static void php_phongo_binary_free_object(phongo_free_object_arg *object TSRMLS_DC) /* {{{ */ { php_phongo_binary_t *intern = Z_OBJ_BINARY(object); zend_object_std_dtor(&intern->std TSRMLS_CC); if (intern->data) { efree(intern->data); } #if PHP_VERSION_ID < 70000 efree(intern); #endif } /* }}} */ phongo_create_object_retval php_phongo_binary_create_object(zend_class_entry *class_type TSRMLS_DC) /* {{{ */ { php_phongo_binary_t *intern = NULL; intern = PHONGO_ALLOC_OBJECT_T(php_phongo_binary_t, class_type); zend_object_std_init(&intern->std, class_type TSRMLS_CC); object_properties_init(&intern->std, class_type); #if PHP_VERSION_ID >= 70000 intern->std.handlers = &php_phongo_handler_binary; return &intern->std; #else { zend_object_value retval; retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_binary_free_object, NULL TSRMLS_CC); retval.handlers = &php_phongo_handler_binary; return retval; } #endif } /* }}} */ HashTable *php_phongo_binary_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */ { php_phongo_binary_t *intern; #if PHP_VERSION_ID >= 70000 zval retval; #else zval retval = zval_used_for_init; #endif intern = Z_BINARY_OBJ_P(object); *is_temp = 1; array_init_size(&retval, 2); ADD_ASSOC_STRINGL(&retval, "data", intern->data, intern->data_len); ADD_ASSOC_LONG_EX(&retval, "type", intern->type); return Z_ARRVAL(retval); } /* }}} */ /* }}} */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(Binary) { zend_class_entry ce; (void)type;(void)module_number; INIT_NS_CLASS_ENTRY(ce, BSON_NAMESPACE, "Binary", php_phongo_binary_me); php_phongo_binary_ce = zend_register_internal_class(&ce TSRMLS_CC); php_phongo_binary_ce->create_object = php_phongo_binary_create_object; PHONGO_CE_INIT(php_phongo_binary_ce); zend_class_implements(php_phongo_binary_ce TSRMLS_CC, 1, php_phongo_type_ce); memcpy(&php_phongo_handler_binary, phongo_get_std_object_handlers(), sizeof(zend_object_handlers)); php_phongo_handler_binary.get_debug_info = php_phongo_binary_get_debug_info; #if PHP_VERSION_ID >= 70000 php_phongo_handler_binary.free_obj = php_phongo_binary_free_object; php_phongo_handler_binary.offset = XtOffsetOf(php_phongo_binary_t, std); #endif zend_declare_class_constant_long(php_phongo_binary_ce, ZEND_STRL("TYPE_GENERIC"), BSON_SUBTYPE_BINARY TSRMLS_CC); zend_declare_class_constant_long(php_phongo_binary_ce, ZEND_STRL("TYPE_FUNCTION"), BSON_SUBTYPE_FUNCTION TSRMLS_CC); zend_declare_class_constant_long(php_phongo_binary_ce, ZEND_STRL("TYPE_OLD_BINARY"), BSON_SUBTYPE_BINARY_DEPRECATED TSRMLS_CC); zend_declare_class_constant_long(php_phongo_binary_ce, ZEND_STRL("TYPE_OLD_UUID"), BSON_SUBTYPE_UUID_DEPRECATED TSRMLS_CC); zend_declare_class_constant_long(php_phongo_binary_ce, ZEND_STRL("TYPE_UUID"), BSON_SUBTYPE_UUID TSRMLS_CC); zend_declare_class_constant_long(php_phongo_binary_ce, ZEND_STRL("TYPE_MD5"), BSON_SUBTYPE_MD5 TSRMLS_CC); zend_declare_class_constant_long(php_phongo_binary_ce, ZEND_STRL("TYPE_USER_DEFINED"), BSON_SUBTYPE_USER TSRMLS_CC); return SUCCESS; } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mongodb-1.1.5/src/BSON/Javascript.c0000664000175000017500000001541012673034026016611 0ustar jmikolajmikola/* +---------------------------------------------------------------------------+ | PHP Driver for MongoDB | +---------------------------------------------------------------------------+ | Copyright 2013-2015 MongoDB, Inc. | | | | Licensed under the Apache License, Version 2.0 (the "License"); | | you may not use this file except in compliance with the License. | | You may obtain a copy of the License at | | | | http://www.apache.org/licenses/LICENSE-2.0 | | | | Unless required by applicable law or agreed to in writing, software | | distributed under the License is distributed on an "AS IS" BASIS, | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | See the License for the specific language governing permissions and | | limitations under the License. | +---------------------------------------------------------------------------+ | Copyright (c) 2014-2015 MongoDB, Inc. | +---------------------------------------------------------------------------+ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif /* External libs */ #include #include /* PHP Core stuff */ #include #include #include #include #include /* Our Compatability header */ #include "phongo_compat.h" /* Our stuffz */ #include "php_phongo.h" #include "php_bson.h" PHONGO_API zend_class_entry *php_phongo_javascript_ce; zend_object_handlers php_phongo_handler_javascript; /* {{{ proto BSON\Javascript Javascript::__construct(string $javascript[, array|object $document]) * The string is JavaScript code. The document is a mapping from identifiers to values, representing the scope in which the string should be evaluated * NOTE: eJSON does not support this type :( */ PHP_METHOD(Javascript, __construct) { php_phongo_javascript_t *intern; zend_error_handling error_handling; char *javascript; phongo_zpp_char_len javascript_len; zval *document = NULL; bson_t scope = BSON_INITIALIZER; zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC); intern = Z_JAVASCRIPT_OBJ_P(getThis()); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|A!", &javascript, &javascript_len, &document) == FAILURE) { zend_restore_error_handling(&error_handling TSRMLS_CC); return; } zend_restore_error_handling(&error_handling TSRMLS_CC); if (document) { phongo_zval_to_bson(document, PHONGO_BSON_NONE, &scope, NULL TSRMLS_CC); } php_phongo_new_javascript_from_javascript_and_scope(0, getThis(), javascript, javascript_len, &scope TSRMLS_CC); bson_destroy(&scope); } /* }}} */ /* {{{ BSON\Javascript */ ZEND_BEGIN_ARG_INFO_EX(ai_Javascript___construct, 0, 0, 1) ZEND_ARG_INFO(0, javascript) ZEND_ARG_INFO(0, scope) ZEND_END_ARG_INFO(); static zend_function_entry php_phongo_javascript_me[] = { PHP_ME(Javascript, __construct, ai_Javascript___construct, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Manager, __wakeUp, NULL, ZEND_ACC_PUBLIC) PHP_FE_END }; /* }}} */ /* {{{ php_phongo_javascript_t object handlers */ static void php_phongo_javascript_free_object(phongo_free_object_arg *object TSRMLS_DC) /* {{{ */ { php_phongo_javascript_t *intern = Z_OBJ_JAVASCRIPT(object); zend_object_std_dtor(&intern->std TSRMLS_CC); if (intern->javascript) { efree(intern->javascript); } if (intern->document) { bson_destroy(intern->document); intern->document = NULL; } #if PHP_VERSION_ID < 70000 efree(intern); #endif } /* }}} */ phongo_create_object_retval php_phongo_javascript_create_object(zend_class_entry *class_type TSRMLS_DC) /* {{{ */ { php_phongo_javascript_t *intern = NULL; intern = PHONGO_ALLOC_OBJECT_T(php_phongo_javascript_t, class_type); zend_object_std_init(&intern->std, class_type TSRMLS_CC); object_properties_init(&intern->std, class_type); intern->document = NULL; #if PHP_VERSION_ID >= 70000 intern->std.handlers = &php_phongo_handler_javascript; return &intern->std; #else { zend_object_value retval; retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_javascript_free_object, NULL TSRMLS_CC); retval.handlers = &php_phongo_handler_javascript; return retval; } #endif } /* }}} */ HashTable *php_phongo_javascript_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */ { php_phongo_javascript_t *intern; #if PHP_VERSION_ID >= 70000 zval retval; #else zval retval = zval_used_for_init; #endif *is_temp = 1; intern = Z_JAVASCRIPT_OBJ_P(object); array_init(&retval); ADD_ASSOC_STRINGL(&retval, "javascript", intern->javascript, intern->javascript_len); if (intern->document) { php_phongo_bson_state state = PHONGO_BSON_STATE_INITIALIZER; if (phongo_bson_to_zval_ex(bson_get_data(intern->document), intern->document->len, &state)) { #if PHP_VERSION_ID >= 70000 Z_ADDREF(state.zchild); ADD_ASSOC_ZVAL_EX(&retval, "scope", &state.zchild); #else Z_ADDREF_P(state.zchild); ADD_ASSOC_ZVAL_EX(&retval, "scope", state.zchild); #endif } else { ADD_ASSOC_NULL_EX(&retval, "scope"); } zval_ptr_dtor(&state.zchild); } return Z_ARRVAL(retval); } /* }}} */ /* }}} */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(Javascript) { zend_class_entry ce; (void)type;(void)module_number; INIT_NS_CLASS_ENTRY(ce, BSON_NAMESPACE, "Javascript", php_phongo_javascript_me); php_phongo_javascript_ce = zend_register_internal_class(&ce TSRMLS_CC); php_phongo_javascript_ce->create_object = php_phongo_javascript_create_object; PHONGO_CE_INIT(php_phongo_javascript_ce); zend_class_implements(php_phongo_javascript_ce TSRMLS_CC, 1, php_phongo_type_ce); memcpy(&php_phongo_handler_javascript, phongo_get_std_object_handlers(), sizeof(zend_object_handlers)); php_phongo_handler_javascript.get_debug_info = php_phongo_javascript_get_debug_info; #if PHP_VERSION_ID >= 70000 php_phongo_handler_javascript.free_obj = php_phongo_javascript_free_object; php_phongo_handler_javascript.offset = XtOffsetOf(php_phongo_javascript_t, std); #endif return SUCCESS; } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mongodb-1.1.5/src/BSON/MaxKey.c0000664000175000017500000001000412673034026015673 0ustar jmikolajmikola/* +---------------------------------------------------------------------------+ | PHP Driver for MongoDB | +---------------------------------------------------------------------------+ | Copyright 2013-2015 MongoDB, Inc. | | | | Licensed under the Apache License, Version 2.0 (the "License"); | | you may not use this file except in compliance with the License. | | You may obtain a copy of the License at | | | | http://www.apache.org/licenses/LICENSE-2.0 | | | | Unless required by applicable law or agreed to in writing, software | | distributed under the License is distributed on an "AS IS" BASIS, | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | See the License for the specific language governing permissions and | | limitations under the License. | +---------------------------------------------------------------------------+ | Copyright (c) 2014-2015 MongoDB, Inc. | +---------------------------------------------------------------------------+ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif /* External libs */ #include #include /* PHP Core stuff */ #include #include #include #include #include /* Our Compatability header */ #include "phongo_compat.h" /* Our stuffz */ #include "php_phongo.h" #include "php_bson.h" PHONGO_API zend_class_entry *php_phongo_maxkey_ce; zend_object_handlers php_phongo_handler_maxkey; /* {{{ BSON\MaxKey */ static zend_function_entry php_phongo_maxkey_me[] = { PHP_ME(Manager, __wakeUp, NULL, ZEND_ACC_PUBLIC) PHP_FE_END }; /* }}} */ /* {{{ php_phongo_maxkey_t object handlers */ static void php_phongo_maxkey_free_object(phongo_free_object_arg *object TSRMLS_DC) /* {{{ */ { php_phongo_maxkey_t *intern = Z_OBJ_MAXKEY(object); zend_object_std_dtor(&intern->std TSRMLS_CC); #if PHP_VERSION_ID < 70000 efree(intern); #endif } /* }}} */ phongo_create_object_retval php_phongo_maxkey_create_object(zend_class_entry *class_type TSRMLS_DC) /* {{{ */ { php_phongo_maxkey_t *intern = NULL; intern = PHONGO_ALLOC_OBJECT_T(php_phongo_maxkey_t, class_type); zend_object_std_init(&intern->std, class_type TSRMLS_CC); object_properties_init(&intern->std, class_type); #if PHP_VERSION_ID >= 70000 intern->std.handlers = &php_phongo_handler_maxkey; return &intern->std; #else { zend_object_value retval; retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_maxkey_free_object, NULL TSRMLS_CC); retval.handlers = &php_phongo_handler_maxkey; return retval; } #endif } /* }}} */ /* }}} */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(MaxKey) { zend_class_entry ce; (void)type;(void)module_number; INIT_NS_CLASS_ENTRY(ce, BSON_NAMESPACE, "MaxKey", php_phongo_maxkey_me); php_phongo_maxkey_ce = zend_register_internal_class(&ce TSRMLS_CC); php_phongo_maxkey_ce->create_object = php_phongo_maxkey_create_object; PHONGO_CE_INIT(php_phongo_maxkey_ce); zend_class_implements(php_phongo_maxkey_ce TSRMLS_CC, 1, php_phongo_type_ce); memcpy(&php_phongo_handler_maxkey, phongo_get_std_object_handlers(), sizeof(zend_object_handlers)); #if PHP_VERSION_ID >= 70000 php_phongo_handler_maxkey.free_obj = php_phongo_maxkey_free_object; php_phongo_handler_maxkey.offset = XtOffsetOf(php_phongo_maxkey_t, std); #endif return SUCCESS; } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mongodb-1.1.5/src/BSON/MinKey.c0000664000175000017500000001000512673034026015672 0ustar jmikolajmikola/* +---------------------------------------------------------------------------+ | PHP Driver for MongoDB | +---------------------------------------------------------------------------+ | Copyright 2013-2015 MongoDB, Inc. | | | | Licensed under the Apache License, Version 2.0 (the "License"); | | you may not use this file except in compliance with the License. | | You may obtain a copy of the License at | | | | http://www.apache.org/licenses/LICENSE-2.0 | | | | Unless required by applicable law or agreed to in writing, software | | distributed under the License is distributed on an "AS IS" BASIS, | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | See the License for the specific language governing permissions and | | limitations under the License. | +---------------------------------------------------------------------------+ | Copyright (c) 2014-2015 MongoDB, Inc. | +---------------------------------------------------------------------------+ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif /* External libs */ #include #include /* PHP Core stuff */ #include #include #include #include #include /* Our Compatability header */ #include "phongo_compat.h" /* Our stuffz */ #include "php_phongo.h" #include "php_bson.h" PHONGO_API zend_class_entry *php_phongo_minkey_ce; zend_object_handlers php_phongo_handler_minkey; /* {{{ BSON\MinKey */ static zend_function_entry php_phongo_minkey_me[] = { PHP_ME(Manager, __wakeUp, NULL, ZEND_ACC_PUBLIC) PHP_FE_END }; /* }}} */ /* {{{ php_phongo_minkey_t object handlers */ static void php_phongo_minkey_free_object(phongo_free_object_arg *object TSRMLS_DC) /* {{{ */ { php_phongo_minkey_t *intern = Z_OBJ_MINKEY(object); zend_object_std_dtor(&intern->std TSRMLS_CC); #if PHP_VERSION_ID < 70000 efree(intern); #endif } /* }}} */ phongo_create_object_retval php_phongo_minkey_create_object(zend_class_entry *class_type TSRMLS_DC) /* {{{ */ { php_phongo_minkey_t *intern = NULL; intern = PHONGO_ALLOC_OBJECT_T(php_phongo_minkey_t, class_type); zend_object_std_init(&intern->std, class_type TSRMLS_CC); object_properties_init(&intern->std, class_type); #if PHP_VERSION_ID >= 70000 intern->std.handlers = &php_phongo_handler_minkey; return &intern->std; #else { zend_object_value retval; retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_minkey_free_object, NULL TSRMLS_CC); retval.handlers = &php_phongo_handler_minkey; return retval; } #endif } /* }}} */ /* }}} */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(MinKey) { zend_class_entry ce; (void)type;(void)module_number; INIT_NS_CLASS_ENTRY(ce, BSON_NAMESPACE, "MinKey", php_phongo_minkey_me); php_phongo_minkey_ce = zend_register_internal_class(&ce TSRMLS_CC); php_phongo_minkey_ce->create_object = php_phongo_minkey_create_object; PHONGO_CE_INIT(php_phongo_minkey_ce); zend_class_implements(php_phongo_minkey_ce TSRMLS_CC, 1, php_phongo_type_ce); memcpy(&php_phongo_handler_minkey, phongo_get_std_object_handlers(), sizeof(zend_object_handlers)); #if PHP_VERSION_ID >= 70000 php_phongo_handler_minkey.free_obj = php_phongo_minkey_free_object; php_phongo_handler_minkey.offset = XtOffsetOf(php_phongo_minkey_t, std); #endif return SUCCESS; } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mongodb-1.1.5/src/BSON/ObjectID.c0000664000175000017500000001520012673034026016123 0ustar jmikolajmikola/* +---------------------------------------------------------------------------+ | PHP Driver for MongoDB | +---------------------------------------------------------------------------+ | Copyright 2013-2015 MongoDB, Inc. | | | | Licensed under the Apache License, Version 2.0 (the "License"); | | you may not use this file except in compliance with the License. | | You may obtain a copy of the License at | | | | http://www.apache.org/licenses/LICENSE-2.0 | | | | Unless required by applicable law or agreed to in writing, software | | distributed under the License is distributed on an "AS IS" BASIS, | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | See the License for the specific language governing permissions and | | limitations under the License. | +---------------------------------------------------------------------------+ | Copyright (c) 2014-2015 MongoDB, Inc. | +---------------------------------------------------------------------------+ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif /* External libs */ #include #include /* PHP Core stuff */ #include #include #include #include #include /* Our Compatability header */ #include "phongo_compat.h" /* Our stuffz */ #include "php_phongo.h" #include "php_bson.h" PHONGO_API zend_class_entry *php_phongo_objectid_ce; zend_object_handlers php_phongo_handler_objectid; /* {{{ proto BSON\ObjectID ObjectID::__construct(string $id) Constructs a new Object ID, optionally from a string */ PHP_METHOD(ObjectID, __construct) { php_phongo_objectid_t *intern; zend_error_handling error_handling; char *id = NULL; phongo_zpp_char_len id_len; zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC); intern = Z_OBJECTID_OBJ_P(getThis()); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!", &id, &id_len) == FAILURE) { zend_restore_error_handling(&error_handling TSRMLS_CC); return; } zend_restore_error_handling(&error_handling TSRMLS_CC); if (id) { zend_str_tolower(id, id_len); if (bson_oid_is_valid(id, id_len)) { bson_oid_t oid; bson_oid_init_from_string(&oid, id); bson_oid_to_string(&oid, intern->oid); } else { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s", "Invalid BSON ID provided"); } } else { bson_oid_t oid; bson_oid_init(&oid, NULL); bson_oid_to_string(&oid, intern->oid); } } /* }}} */ /* {{{ proto void ObjectID::__toString() */ PHP_METHOD(ObjectID, __toString) { php_phongo_objectid_t *intern; intern = Z_OBJECTID_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } PHONGO_RETURN_STRINGL(intern->oid, 24); } /* }}} */ /* {{{ BSON\ObjectID */ ZEND_BEGIN_ARG_INFO_EX(ai_ObjectID___construct, 0, 0, 0) ZEND_ARG_INFO(0, id) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_ObjectID___toString, 0, 0, 0) ZEND_END_ARG_INFO(); static zend_function_entry php_phongo_objectid_me[] = { PHP_ME(ObjectID, __construct, ai_ObjectID___construct, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(ObjectID, __toString, ai_ObjectID___toString, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Manager, __wakeUp, NULL, ZEND_ACC_PUBLIC) PHP_FE_END }; /* }}} */ /* {{{ php_phongo_objectid_t object handlers */ static void php_phongo_objectid_free_object(phongo_free_object_arg *object TSRMLS_DC) /* {{{ */ { php_phongo_objectid_t *intern = Z_OBJ_OBJECTID(object); zend_object_std_dtor(&intern->std TSRMLS_CC); #if PHP_VERSION_ID < 70000 efree(intern); #endif } /* }}} */ phongo_create_object_retval php_phongo_objectid_create_object(zend_class_entry *class_type TSRMLS_DC) /* {{{ */ { php_phongo_objectid_t *intern = NULL; intern = PHONGO_ALLOC_OBJECT_T(php_phongo_objectid_t, class_type); zend_object_std_init(&intern->std, class_type TSRMLS_CC); object_properties_init(&intern->std, class_type); #if PHP_VERSION_ID >= 70000 intern->std.handlers = &php_phongo_handler_objectid; return &intern->std; #else { zend_object_value retval; retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_objectid_free_object, NULL TSRMLS_CC); retval.handlers = &php_phongo_handler_objectid; return retval; } #endif } /* }}} */ static int php_phongo_objectid_compare_objects(zval *o1, zval *o2 TSRMLS_DC) /* {{{ */ { php_phongo_objectid_t *intern1; php_phongo_objectid_t *intern2; intern1 = Z_OBJECTID_OBJ_P(o1); intern2 = Z_OBJECTID_OBJ_P(o2); return strcmp(intern1->oid, intern2->oid); } /* }}} */ HashTable *php_phongo_objectid_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */ { php_phongo_objectid_t *intern; #if PHP_VERSION_ID >= 70000 zval retval; #else zval retval = zval_used_for_init; #endif *is_temp = 1; intern = Z_OBJECTID_OBJ_P(object); array_init(&retval); ADD_ASSOC_STRINGL(&retval, "oid", intern->oid, 24); return Z_ARRVAL(retval); } /* }}} */ /* }}} */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(ObjectID) { zend_class_entry ce; (void)type;(void)module_number; INIT_NS_CLASS_ENTRY(ce, BSON_NAMESPACE, "ObjectID", php_phongo_objectid_me); php_phongo_objectid_ce = zend_register_internal_class(&ce TSRMLS_CC); php_phongo_objectid_ce->create_object = php_phongo_objectid_create_object; PHONGO_CE_INIT(php_phongo_objectid_ce); zend_class_implements(php_phongo_objectid_ce TSRMLS_CC, 1, php_phongo_type_ce); memcpy(&php_phongo_handler_objectid, phongo_get_std_object_handlers(), sizeof(zend_object_handlers)); php_phongo_handler_objectid.compare_objects = php_phongo_objectid_compare_objects; php_phongo_handler_objectid.get_debug_info = php_phongo_objectid_get_debug_info; #if PHP_VERSION_ID >= 70000 php_phongo_handler_objectid.free_obj = php_phongo_objectid_free_object; php_phongo_handler_objectid.offset = XtOffsetOf(php_phongo_objectid_t, std); #endif return SUCCESS; } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mongodb-1.1.5/src/BSON/Persistable.c0000664000175000017500000000515312673034026016763 0ustar jmikolajmikola/* +---------------------------------------------------------------------------+ | PHP Driver for MongoDB | +---------------------------------------------------------------------------+ | Copyright 2013-2015 MongoDB, Inc. | | | | Licensed under the Apache License, Version 2.0 (the "License"); | | you may not use this file except in compliance with the License. | | You may obtain a copy of the License at | | | | http://www.apache.org/licenses/LICENSE-2.0 | | | | Unless required by applicable law or agreed to in writing, software | | distributed under the License is distributed on an "AS IS" BASIS, | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | See the License for the specific language governing permissions and | | limitations under the License. | +---------------------------------------------------------------------------+ | Copyright (c) 2014-2015 MongoDB, Inc. | +---------------------------------------------------------------------------+ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif /* External libs */ #include #include /* PHP Core stuff */ #include #include #include #include #include /* Our Compatability header */ #include "phongo_compat.h" /* Our stuffz */ #include "php_phongo.h" #include "php_bson.h" PHONGO_API zend_class_entry *php_phongo_persistable_ce; /* {{{ BSON\Persistable */ static zend_function_entry php_phongo_persistable_me[] = { PHP_FE_END }; /* }}} */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(Persistable) { zend_class_entry ce; (void)type;(void)module_number; INIT_NS_CLASS_ENTRY(ce, BSON_NAMESPACE, "Persistable", php_phongo_persistable_me); php_phongo_persistable_ce = zend_register_internal_interface(&ce TSRMLS_CC); zend_class_implements(php_phongo_persistable_ce TSRMLS_CC, 2, php_phongo_unserializable_ce, php_phongo_serializable_ce); return SUCCESS; } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mongodb-1.1.5/src/BSON/Regex.c0000664000175000017500000001635512673034026015566 0ustar jmikolajmikola/* +---------------------------------------------------------------------------+ | PHP Driver for MongoDB | +---------------------------------------------------------------------------+ | Copyright 2013-2015 MongoDB, Inc. | | | | Licensed under the Apache License, Version 2.0 (the "License"); | | you may not use this file except in compliance with the License. | | You may obtain a copy of the License at | | | | http://www.apache.org/licenses/LICENSE-2.0 | | | | Unless required by applicable law or agreed to in writing, software | | distributed under the License is distributed on an "AS IS" BASIS, | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | See the License for the specific language governing permissions and | | limitations under the License. | +---------------------------------------------------------------------------+ | Copyright (c) 2014-2015 MongoDB, Inc. | +---------------------------------------------------------------------------+ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif /* External libs */ #include #include /* PHP Core stuff */ #include #include #include #include #include /* Our Compatability header */ #include "phongo_compat.h" /* Our stuffz */ #include "php_phongo.h" #include "php_bson.h" PHONGO_API zend_class_entry *php_phongo_regex_ce; zend_object_handlers php_phongo_handler_regex; /* {{{ proto BSON\Regex Regex::__construct(string $pattern, string $flags) Constructs a new regular expression. */ PHP_METHOD(Regex, __construct) { php_phongo_regex_t *intern; zend_error_handling error_handling; char *pattern; phongo_zpp_char_len pattern_len; char *flags; phongo_zpp_char_len flags_len; zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC); intern = Z_REGEX_OBJ_P(getThis()); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &pattern, &pattern_len, &flags, &flags_len) == FAILURE) { zend_restore_error_handling(&error_handling TSRMLS_CC); return; } zend_restore_error_handling(&error_handling TSRMLS_CC); intern->pattern = estrndup(pattern, pattern_len); intern->pattern_len = pattern_len; intern->flags = estrndup(flags, flags_len); intern->flags_len = flags_len; } /* }}} */ /* {{{ proto void Regex::getPattern() */ PHP_METHOD(Regex, getPattern) { php_phongo_regex_t *intern; intern = Z_REGEX_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } PHONGO_RETURN_STRINGL(intern->pattern, intern->pattern_len); } /* }}} */ /* {{{ proto void Regex::getFlags() */ PHP_METHOD(Regex, getFlags) { php_phongo_regex_t *intern; intern = Z_REGEX_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } PHONGO_RETURN_STRINGL(intern->flags, intern->flags_len); } /* }}} */ /* {{{ proto void Regex::__toString() */ PHP_METHOD(Regex, __toString) { php_phongo_regex_t *intern; char *regex; int regex_len; intern = Z_REGEX_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } regex_len = spprintf(®ex, 0, "/%s/%s", intern->pattern, intern->flags); PHONGO_RETVAL_STRINGL(regex, regex_len); efree(regex); } /* }}} */ /* {{{ BSON\Regex */ ZEND_BEGIN_ARG_INFO_EX(ai_Regex___construct, 0, 0, 2) ZEND_ARG_INFO(0, pattern) ZEND_ARG_INFO(0, flags) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_Regex_getPattern, 0, 0, 0) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_Regex_getFlags, 0, 0, 0) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_Regex___toString, 0, 0, 0) ZEND_END_ARG_INFO(); static zend_function_entry php_phongo_regex_me[] = { PHP_ME(Regex, __construct, ai_Regex___construct, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Regex, getPattern, ai_Regex_getPattern, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Regex, getFlags, ai_Regex_getFlags, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Regex, __toString, ai_Regex___toString, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Manager, __wakeUp, NULL, ZEND_ACC_PUBLIC) PHP_FE_END }; /* }}} */ /* {{{ php_phongo_regex_t object handlers */ static void php_phongo_regex_free_object(phongo_free_object_arg *object TSRMLS_DC) /* {{{ */ { php_phongo_regex_t *intern = Z_OBJ_REGEX(object); zend_object_std_dtor(&intern->std TSRMLS_CC); if (intern->pattern) { efree(intern->pattern); } if (intern->flags) { efree(intern->flags); } #if PHP_VERSION_ID < 70000 efree(intern); #endif } /* }}} */ phongo_create_object_retval php_phongo_regex_create_object(zend_class_entry *class_type TSRMLS_DC) /* {{{ */ { php_phongo_regex_t *intern = NULL; intern = PHONGO_ALLOC_OBJECT_T(php_phongo_regex_t, class_type); zend_object_std_init(&intern->std, class_type TSRMLS_CC); object_properties_init(&intern->std, class_type); #if PHP_VERSION_ID >= 70000 intern->std.handlers = &php_phongo_handler_regex; return &intern->std; #else { zend_object_value retval; retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_regex_free_object, NULL TSRMLS_CC); retval.handlers = &php_phongo_handler_regex; return retval; } #endif } /* }}} */ HashTable *php_phongo_regex_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */ { php_phongo_regex_t *intern; #if PHP_VERSION_ID >= 70000 zval retval; #else zval retval = zval_used_for_init; #endif *is_temp = 1; intern = Z_REGEX_OBJ_P(object); array_init(&retval); ADD_ASSOC_STRINGL(&retval, "pattern", intern->pattern, intern->pattern_len); ADD_ASSOC_STRINGL(&retval, "flags", intern->flags, intern->flags_len); return Z_ARRVAL(retval); } /* }}} */ /* }}} */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(Regex) { zend_class_entry ce; (void)type;(void)module_number; INIT_NS_CLASS_ENTRY(ce, BSON_NAMESPACE, "Regex", php_phongo_regex_me); php_phongo_regex_ce = zend_register_internal_class(&ce TSRMLS_CC); php_phongo_regex_ce->create_object = php_phongo_regex_create_object; PHONGO_CE_INIT(php_phongo_regex_ce); zend_class_implements(php_phongo_regex_ce TSRMLS_CC, 1, php_phongo_type_ce); memcpy(&php_phongo_handler_regex, phongo_get_std_object_handlers(), sizeof(zend_object_handlers)); php_phongo_handler_regex.get_debug_info = php_phongo_regex_get_debug_info; #if PHP_VERSION_ID >= 70000 php_phongo_handler_regex.free_obj = php_phongo_regex_free_object; php_phongo_handler_regex.offset = XtOffsetOf(php_phongo_regex_t, std); #endif return SUCCESS; } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mongodb-1.1.5/src/BSON/Serializable.c0000664000175000017500000000536012673034026017114 0ustar jmikolajmikola/* +---------------------------------------------------------------------------+ | PHP Driver for MongoDB | +---------------------------------------------------------------------------+ | Copyright 2013-2015 MongoDB, Inc. | | | | Licensed under the Apache License, Version 2.0 (the "License"); | | you may not use this file except in compliance with the License. | | You may obtain a copy of the License at | | | | http://www.apache.org/licenses/LICENSE-2.0 | | | | Unless required by applicable law or agreed to in writing, software | | distributed under the License is distributed on an "AS IS" BASIS, | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | See the License for the specific language governing permissions and | | limitations under the License. | +---------------------------------------------------------------------------+ | Copyright (c) 2014-2015 MongoDB, Inc. | +---------------------------------------------------------------------------+ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif /* External libs */ #include #include /* PHP Core stuff */ #include #include #include #include #include /* Our Compatability header */ #include "phongo_compat.h" /* Our stuffz */ #include "php_phongo.h" #include "php_bson.h" PHONGO_API zend_class_entry *php_phongo_serializable_ce; /* {{{ BSON\Serializable */ ZEND_BEGIN_ARG_INFO_EX(ai_serializable_bsonserialize, 0, 0, 0) ZEND_END_ARG_INFO(); static zend_function_entry php_phongo_serializable_me[] = { ZEND_ABSTRACT_ME(Serializable, bsonSerialize, ai_serializable_bsonserialize) PHP_FE_END }; /* }}} */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(Serializable) { zend_class_entry ce; (void)type;(void)module_number; INIT_NS_CLASS_ENTRY(ce, BSON_NAMESPACE, "Serializable", php_phongo_serializable_me); php_phongo_serializable_ce = zend_register_internal_interface(&ce TSRMLS_CC); zend_class_implements(php_phongo_serializable_ce TSRMLS_CC, 1, php_phongo_type_ce); return SUCCESS; } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mongodb-1.1.5/src/BSON/Timestamp.c0000664000175000017500000001545212673034026016454 0ustar jmikolajmikola/* +---------------------------------------------------------------------------+ | PHP Driver for MongoDB | +---------------------------------------------------------------------------+ | Copyright 2013-2015 MongoDB, Inc. | | | | Licensed under the Apache License, Version 2.0 (the "License"); | | you may not use this file except in compliance with the License. | | You may obtain a copy of the License at | | | | http://www.apache.org/licenses/LICENSE-2.0 | | | | Unless required by applicable law or agreed to in writing, software | | distributed under the License is distributed on an "AS IS" BASIS, | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | See the License for the specific language governing permissions and | | limitations under the License. | +---------------------------------------------------------------------------+ | Copyright (c) 2014-2015 MongoDB, Inc. | +---------------------------------------------------------------------------+ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif /* External libs */ #include #include /* PHP Core stuff */ #include #include #include #include #include /* Our Compatability header */ #include "phongo_compat.h" /* Our stuffz */ #include "php_phongo.h" #include "php_bson.h" PHONGO_API zend_class_entry *php_phongo_timestamp_ce; zend_object_handlers php_phongo_handler_timestamp; /* {{{ proto BSON\Timestamp Timestamp::__construct(integer $increment, int $timestamp) Construct a new BSON Timestamp (4bytes increment, 4bytes timestamp) */ PHP_METHOD(Timestamp, __construct) { php_phongo_timestamp_t *intern; zend_error_handling error_handling; phongo_long increment; phongo_long timestamp; zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC); intern = Z_TIMESTAMP_OBJ_P(getThis()); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &increment, ×tamp) == FAILURE) { zend_restore_error_handling(&error_handling TSRMLS_CC); return; } zend_restore_error_handling(&error_handling TSRMLS_CC); if (increment < 0 || increment > UINT32_MAX) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected increment to be an unsigned 32-bit integer, %" PHONGO_LONG_FORMAT " given", increment); return; } if (timestamp < 0 || timestamp > UINT32_MAX) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected timestamp to be an unsigned 32-bit integer, %" PHONGO_LONG_FORMAT " given", timestamp); return; } intern->increment = increment; intern->timestamp = timestamp; } /* }}} */ /* {{{ proto string Timestamp::__toString() Returns [increment:timestamp] */ PHP_METHOD(Timestamp, __toString) { php_phongo_timestamp_t *intern; char *retval; int retval_len; intern = Z_TIMESTAMP_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } retval_len = spprintf(&retval, 0, "[%" PRIu32 ":%" PRIu32 "]", intern->increment, intern->timestamp); PHONGO_RETVAL_STRINGL(retval, retval_len); efree(retval); } /* }}} */ /* {{{ BSON\Timestamp */ ZEND_BEGIN_ARG_INFO_EX(ai_Timestamp___construct, 0, 0, 2) ZEND_ARG_INFO(0, increment) ZEND_ARG_INFO(0, timestamp) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_Timestamp___toString, 0, 0, 0) ZEND_END_ARG_INFO(); static zend_function_entry php_phongo_timestamp_me[] = { PHP_ME(Timestamp, __construct, ai_Timestamp___construct, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Timestamp, __toString, ai_Timestamp___toString, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Manager, __wakeUp, NULL, ZEND_ACC_PUBLIC) PHP_FE_END }; /* }}} */ /* {{{ php_phongo_timestamp_t object handlers */ static void php_phongo_timestamp_free_object(phongo_free_object_arg *object TSRMLS_DC) /* {{{ */ { php_phongo_timestamp_t *intern = Z_OBJ_TIMESTAMP(object); zend_object_std_dtor(&intern->std TSRMLS_CC); #if PHP_VERSION_ID < 70000 efree(intern); #endif } /* }}} */ phongo_create_object_retval php_phongo_timestamp_create_object(zend_class_entry *class_type TSRMLS_DC) /* {{{ */ { php_phongo_timestamp_t *intern = NULL; intern = PHONGO_ALLOC_OBJECT_T(php_phongo_timestamp_t, class_type); zend_object_std_init(&intern->std, class_type TSRMLS_CC); object_properties_init(&intern->std, class_type); #if PHP_VERSION_ID >= 70000 intern->std.handlers = &php_phongo_handler_timestamp; return &intern->std; #else { zend_object_value retval; retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_timestamp_free_object, NULL TSRMLS_CC); retval.handlers = &php_phongo_handler_timestamp; return retval; } #endif } /* }}} */ HashTable *php_phongo_timestamp_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */ { php_phongo_timestamp_t *intern; #if PHP_VERSION_ID >= 70000 zval retval; #else zval retval = zval_used_for_init; #endif *is_temp = 1; intern = Z_TIMESTAMP_OBJ_P(object); array_init(&retval); ADD_ASSOC_LONG_EX(&retval, "increment", intern->increment); ADD_ASSOC_LONG_EX(&retval, "timestamp", intern->timestamp); return Z_ARRVAL(retval); } /* }}} */ /* }}} */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(Timestamp) { zend_class_entry ce; (void)type;(void)module_number; INIT_NS_CLASS_ENTRY(ce, BSON_NAMESPACE, "Timestamp", php_phongo_timestamp_me); php_phongo_timestamp_ce = zend_register_internal_class(&ce TSRMLS_CC); php_phongo_timestamp_ce->create_object = php_phongo_timestamp_create_object; PHONGO_CE_INIT(php_phongo_timestamp_ce); zend_class_implements(php_phongo_timestamp_ce TSRMLS_CC, 1, php_phongo_type_ce); memcpy(&php_phongo_handler_timestamp, phongo_get_std_object_handlers(), sizeof(zend_object_handlers)); php_phongo_handler_timestamp.get_debug_info = php_phongo_timestamp_get_debug_info; #if PHP_VERSION_ID >= 70000 php_phongo_handler_timestamp.free_obj = php_phongo_timestamp_free_object; php_phongo_handler_timestamp.offset = XtOffsetOf(php_phongo_timestamp_t, std); #endif return SUCCESS; } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mongodb-1.1.5/src/BSON/Type.c0000664000175000017500000000470012673034026015424 0ustar jmikolajmikola/* +---------------------------------------------------------------------------+ | PHP Driver for MongoDB | +---------------------------------------------------------------------------+ | Copyright 2013-2015 MongoDB, Inc. | | | | Licensed under the Apache License, Version 2.0 (the "License"); | | you may not use this file except in compliance with the License. | | You may obtain a copy of the License at | | | | http://www.apache.org/licenses/LICENSE-2.0 | | | | Unless required by applicable law or agreed to in writing, software | | distributed under the License is distributed on an "AS IS" BASIS, | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | See the License for the specific language governing permissions and | | limitations under the License. | +---------------------------------------------------------------------------+ | Copyright (c) 2014-2015 MongoDB, Inc. | +---------------------------------------------------------------------------+ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif /* External libs */ #include #include /* PHP Core stuff */ #include #include #include #include #include /* Our Compatability header */ #include "phongo_compat.h" /* Our stuffz */ #include "php_phongo.h" #include "php_bson.h" PHONGO_API zend_class_entry *php_phongo_type_ce; /* {{{ BSON\Type */ static zend_function_entry php_phongo_type_me[] = { PHP_FE_END }; /* }}} */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(Type) { zend_class_entry ce; (void)type;(void)module_number; INIT_NS_CLASS_ENTRY(ce, BSON_NAMESPACE, "Type", php_phongo_type_me); php_phongo_type_ce = zend_register_internal_interface(&ce TSRMLS_CC); return SUCCESS; } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mongodb-1.1.5/src/BSON/UTCDateTime.c0000664000175000017500000001661112673034026016557 0ustar jmikolajmikola/* +---------------------------------------------------------------------------+ | PHP Driver for MongoDB | +---------------------------------------------------------------------------+ | Copyright 2013-2015 MongoDB, Inc. | | | | Licensed under the Apache License, Version 2.0 (the "License"); | | you may not use this file except in compliance with the License. | | You may obtain a copy of the License at | | | | http://www.apache.org/licenses/LICENSE-2.0 | | | | Unless required by applicable law or agreed to in writing, software | | distributed under the License is distributed on an "AS IS" BASIS, | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | See the License for the specific language governing permissions and | | limitations under the License. | +---------------------------------------------------------------------------+ | Copyright (c) 2014-2015 MongoDB, Inc. | +---------------------------------------------------------------------------+ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif /* External libs */ #include #include /* PHP Core stuff */ #include #include #include #include #include /* Our Compatability header */ #include "phongo_compat.h" /* Our stuffz */ #include "php_phongo.h" #include "php_bson.h" PHONGO_API zend_class_entry *php_phongo_utcdatetime_ce; zend_object_handlers php_phongo_handler_utcdatetime; /* {{{ proto BSON\UTCDateTime UTCDateTime::__construct(integer $milliseconds) Construct a new UTCDateTime */ PHP_METHOD(UTCDateTime, __construct) { php_phongo_utcdatetime_t *intern; zend_error_handling error_handling; zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC); intern = Z_UTCDATETIME_OBJ_P(getThis()); #if SIZEOF_PHONGO_LONG == 8 { phongo_long milliseconds; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &milliseconds) == FAILURE) { zend_restore_error_handling(&error_handling TSRMLS_CC); return; } intern->milliseconds = milliseconds; } #elif SIZEOF_PHONGO_LONG == 4 { char *s_milliseconds; phongo_zpp_char_len s_milliseconds_len; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &s_milliseconds, &s_milliseconds_len) == FAILURE) { zend_restore_error_handling(&error_handling TSRMLS_CC); return; } intern->milliseconds = STRTOLL(s_milliseconds); } #else # error Unsupported architecture (integers are neither 32-bit nor 64-bit) #endif zend_restore_error_handling(&error_handling TSRMLS_CC); } /* }}} */ /* {{{ proto string UTCDateTime::__toString() Returns the string representation of the UTCDateTime */ PHP_METHOD(UTCDateTime, __toString) { php_phongo_utcdatetime_t *intern; char *tmp; int tmp_len; intern = Z_UTCDATETIME_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } tmp_len = spprintf(&tmp, 0, "%" PRId64, intern->milliseconds); PHONGO_RETVAL_STRINGL(tmp, tmp_len); efree(tmp); } /* }}} */ /* {{{ proto string UTCDateTime::toDateTime() Returns DateTime object representing this UTCDateTime */ PHP_METHOD(UTCDateTime, toDateTime) { php_phongo_utcdatetime_t *intern; intern = Z_UTCDATETIME_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } php_phongo_new_datetime_from_utcdatetime(return_value, intern->milliseconds TSRMLS_CC); } /* }}} */ /* {{{ BSON\UTCDateTime */ ZEND_BEGIN_ARG_INFO_EX(ai_UTCDateTime___construct, 0, 0, 1) ZEND_ARG_INFO(0, milliseconds) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_UTCDateTime___toString, 0, 0, 0) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_UTCDateTime_toDateTime, 0, 0, 0) ZEND_END_ARG_INFO(); static zend_function_entry php_phongo_utcdatetime_me[] = { PHP_ME(UTCDateTime, __construct, ai_UTCDateTime___construct, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(UTCDateTime, __toString, ai_UTCDateTime___toString, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(UTCDateTime, toDateTime, ai_UTCDateTime_toDateTime, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Manager, __wakeUp, NULL, ZEND_ACC_PUBLIC) PHP_FE_END }; /* }}} */ /* {{{ php_phongo_utcdatetime_t object handlers */ static void php_phongo_utcdatetime_free_object(phongo_free_object_arg *object TSRMLS_DC) /* {{{ */ { php_phongo_utcdatetime_t *intern = Z_OBJ_UTCDATETIME(object); zend_object_std_dtor(&intern->std TSRMLS_CC); #if PHP_VERSION_ID < 70000 efree(intern); #endif } /* }}} */ phongo_create_object_retval php_phongo_utcdatetime_create_object(zend_class_entry *class_type TSRMLS_DC) /* {{{ */ { php_phongo_utcdatetime_t *intern = NULL; intern = PHONGO_ALLOC_OBJECT_T(php_phongo_utcdatetime_t, class_type); zend_object_std_init(&intern->std, class_type TSRMLS_CC); object_properties_init(&intern->std, class_type); #if PHP_VERSION_ID >= 70000 intern->std.handlers = &php_phongo_handler_utcdatetime; return &intern->std; #else { zend_object_value retval; retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_utcdatetime_free_object, NULL TSRMLS_CC); retval.handlers = &php_phongo_handler_utcdatetime; return retval; } #endif } /* }}} */ HashTable *php_phongo_utcdatetime_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */ { php_phongo_utcdatetime_t *intern; #if PHP_VERSION_ID >= 70000 zval retval; #else zval retval = zval_used_for_init; #endif *is_temp = 1; intern = Z_UTCDATETIME_OBJ_P(object); array_init(&retval); #if SIZEOF_LONG == 4 { char tmp[24]; int tmp_len; tmp_len = snprintf(tmp, sizeof(tmp), "%" PRId64, intern->milliseconds); ADD_ASSOC_STRINGL(&retval, "milliseconds", tmp, tmp_len); } #else ADD_ASSOC_LONG_EX(&retval, "milliseconds", intern->milliseconds); #endif return Z_ARRVAL(retval); } /* }}} */ /* }}} */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(UTCDateTime) { zend_class_entry ce; (void)type;(void)module_number; INIT_NS_CLASS_ENTRY(ce, BSON_NAMESPACE, "UTCDateTime", php_phongo_utcdatetime_me); php_phongo_utcdatetime_ce = zend_register_internal_class(&ce TSRMLS_CC); php_phongo_utcdatetime_ce->create_object = php_phongo_utcdatetime_create_object; PHONGO_CE_INIT(php_phongo_utcdatetime_ce); zend_class_implements(php_phongo_utcdatetime_ce TSRMLS_CC, 1, php_phongo_type_ce); memcpy(&php_phongo_handler_utcdatetime, phongo_get_std_object_handlers(), sizeof(zend_object_handlers)); php_phongo_handler_utcdatetime.get_debug_info = php_phongo_utcdatetime_get_debug_info; #if PHP_VERSION_ID >= 70000 php_phongo_handler_utcdatetime.free_obj = php_phongo_utcdatetime_free_object; php_phongo_handler_utcdatetime.offset = XtOffsetOf(php_phongo_utcdatetime_t, std); #endif return SUCCESS; } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mongodb-1.1.5/src/BSON/Unserializable.c0000664000175000017500000000532612673034026017461 0ustar jmikolajmikola/* +---------------------------------------------------------------------------+ | PHP Driver for MongoDB | +---------------------------------------------------------------------------+ | Copyright 2013-2015 MongoDB, Inc. | | | | Licensed under the Apache License, Version 2.0 (the "License"); | | you may not use this file except in compliance with the License. | | You may obtain a copy of the License at | | | | http://www.apache.org/licenses/LICENSE-2.0 | | | | Unless required by applicable law or agreed to in writing, software | | distributed under the License is distributed on an "AS IS" BASIS, | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | See the License for the specific language governing permissions and | | limitations under the License. | +---------------------------------------------------------------------------+ | Copyright (c) 2014-2015 MongoDB, Inc. | +---------------------------------------------------------------------------+ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif /* External libs */ #include #include /* PHP Core stuff */ #include #include #include #include #include /* Our Compatability header */ #include "phongo_compat.h" /* Our stuffz */ #include "php_phongo.h" #include "php_bson.h" PHONGO_API zend_class_entry *php_phongo_unserializable_ce; /* {{{ BSON\Unserializable */ ZEND_BEGIN_ARG_INFO_EX(ai_unserializable_bsonunserialize, 0, 0, 1) ZEND_ARG_ARRAY_INFO(0, data, 0) ZEND_END_ARG_INFO(); static zend_function_entry php_phongo_unserializable_me[] = { ZEND_ABSTRACT_ME(Unserializable, bsonUnserialize, ai_unserializable_bsonunserialize) PHP_FE_END }; /* }}} */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(Unserializable) { zend_class_entry ce; (void)type;(void)module_number; INIT_NS_CLASS_ENTRY(ce, BSON_NAMESPACE, "Unserializable", php_phongo_unserializable_me); php_phongo_unserializable_ce = zend_register_internal_interface(&ce TSRMLS_CC); return SUCCESS; } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mongodb-1.1.5/src/MongoDB/Exception/AuthenticationException.c0000664000175000017500000000550712673034026024031 0ustar jmikolajmikola/* +---------------------------------------------------------------------------+ | PHP Driver for MongoDB | +---------------------------------------------------------------------------+ | Copyright 2013-2015 MongoDB, Inc. | | | | Licensed under the Apache License, Version 2.0 (the "License"); | | you may not use this file except in compliance with the License. | | You may obtain a copy of the License at | | | | http://www.apache.org/licenses/LICENSE-2.0 | | | | Unless required by applicable law or agreed to in writing, software | | distributed under the License is distributed on an "AS IS" BASIS, | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | See the License for the specific language governing permissions and | | limitations under the License. | +---------------------------------------------------------------------------+ | Copyright (c) 2014-2015 MongoDB, Inc. | +---------------------------------------------------------------------------+ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif /* External libs */ #include #include /* PHP Core stuff */ #include #include #include #include #include /* Our Compatability header */ #include "phongo_compat.h" /* Our stuffz */ #include "php_phongo.h" #include "php_bson.h" #include PHONGO_API zend_class_entry *php_phongo_authenticationexception_ce; /* {{{ MongoDB\Driver\AuthenticationException */ static zend_function_entry php_phongo_authenticationexception_me[] = { PHP_FE_END }; /* }}} */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(AuthenticationException) { zend_class_entry ce; (void)type;(void)module_number; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver\\Exception", "AuthenticationException", php_phongo_authenticationexception_me); #if PHP_VERSION_ID >= 70000 php_phongo_authenticationexception_ce = zend_register_internal_class_ex(&ce, php_phongo_connectionexception_ce); #else php_phongo_authenticationexception_ce = zend_register_internal_class_ex(&ce, php_phongo_connectionexception_ce, NULL TSRMLS_CC); #endif return SUCCESS; } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mongodb-1.1.5/src/MongoDB/Exception/BulkWriteException.c0000664000175000017500000000542512673034026022761 0ustar jmikolajmikola/* +---------------------------------------------------------------------------+ | PHP Driver for MongoDB | +---------------------------------------------------------------------------+ | Copyright 2013-2015 MongoDB, Inc. | | | | Licensed under the Apache License, Version 2.0 (the "License"); | | you may not use this file except in compliance with the License. | | You may obtain a copy of the License at | | | | http://www.apache.org/licenses/LICENSE-2.0 | | | | Unless required by applicable law or agreed to in writing, software | | distributed under the License is distributed on an "AS IS" BASIS, | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | See the License for the specific language governing permissions and | | limitations under the License. | +---------------------------------------------------------------------------+ | Copyright (c) 2014-2015 MongoDB, Inc. | +---------------------------------------------------------------------------+ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif /* External libs */ #include #include /* PHP Core stuff */ #include #include #include #include #include /* Our Compatability header */ #include "phongo_compat.h" /* Our stuffz */ #include "php_phongo.h" #include "php_bson.h" #include PHONGO_API zend_class_entry *php_phongo_bulkwriteexception_ce; /* {{{ MongoDB\Driver\BulkWriteException */ static zend_function_entry php_phongo_bulkwriteexception_me[] = { PHP_FE_END }; /* }}} */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(BulkWriteException) { zend_class_entry ce; (void)type;(void)module_number; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver\\Exception", "BulkWriteException", php_phongo_bulkwriteexception_me); #if PHP_VERSION_ID >= 70000 php_phongo_bulkwriteexception_ce = zend_register_internal_class_ex(&ce, php_phongo_writeexception_ce); #else php_phongo_bulkwriteexception_ce = zend_register_internal_class_ex(&ce, php_phongo_writeexception_ce, NULL TSRMLS_CC); #endif return SUCCESS; } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mongodb-1.1.5/src/MongoDB/Exception/ConnectionException.c0000664000175000017500000000544112673034026023146 0ustar jmikolajmikola/* +---------------------------------------------------------------------------+ | PHP Driver for MongoDB | +---------------------------------------------------------------------------+ | Copyright 2013-2015 MongoDB, Inc. | | | | Licensed under the Apache License, Version 2.0 (the "License"); | | you may not use this file except in compliance with the License. | | You may obtain a copy of the License at | | | | http://www.apache.org/licenses/LICENSE-2.0 | | | | Unless required by applicable law or agreed to in writing, software | | distributed under the License is distributed on an "AS IS" BASIS, | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | See the License for the specific language governing permissions and | | limitations under the License. | +---------------------------------------------------------------------------+ | Copyright (c) 2014-2015 MongoDB, Inc. | +---------------------------------------------------------------------------+ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif /* External libs */ #include #include /* PHP Core stuff */ #include #include #include #include #include /* Our Compatability header */ #include "phongo_compat.h" /* Our stuffz */ #include "php_phongo.h" #include "php_bson.h" #include PHONGO_API zend_class_entry *php_phongo_connectionexception_ce; /* {{{ MongoDB\Driver\ConnectionException */ static zend_function_entry php_phongo_connectionexception_me[] = { PHP_FE_END }; /* }}} */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(ConnectionException) { zend_class_entry ce; (void)type;(void)module_number; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver\\Exception", "ConnectionException", php_phongo_connectionexception_me); #if PHP_VERSION_ID >= 70000 php_phongo_connectionexception_ce = zend_register_internal_class_ex(&ce, php_phongo_runtimeexception_ce); #else php_phongo_connectionexception_ce = zend_register_internal_class_ex(&ce, php_phongo_runtimeexception_ce, NULL TSRMLS_CC); #endif return SUCCESS; } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mongodb-1.1.5/src/MongoDB/Exception/ConnectionTimeoutException.c0000664000175000017500000000562312673034026024517 0ustar jmikolajmikola/* +---------------------------------------------------------------------------+ | PHP Driver for MongoDB | +---------------------------------------------------------------------------+ | Copyright 2013-2015 MongoDB, Inc. | | | | Licensed under the Apache License, Version 2.0 (the "License"); | | you may not use this file except in compliance with the License. | | You may obtain a copy of the License at | | | | http://www.apache.org/licenses/LICENSE-2.0 | | | | Unless required by applicable law or agreed to in writing, software | | distributed under the License is distributed on an "AS IS" BASIS, | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | See the License for the specific language governing permissions and | | limitations under the License. | +---------------------------------------------------------------------------+ | Copyright (c) 2014-2015 MongoDB, Inc. | +---------------------------------------------------------------------------+ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif /* External libs */ #include #include /* PHP Core stuff */ #include #include #include #include #include /* Our Compatability header */ #include "phongo_compat.h" /* Our stuffz */ #include "php_phongo.h" #include "php_bson.h" #include PHONGO_API zend_class_entry *php_phongo_connectiontimeoutexception_ce; /* {{{ MongoDB\Driver\ConnectionTimeoutException */ static zend_function_entry php_phongo_connectiontimeoutexception_me[] = { PHP_FE_END }; /* }}} */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(ConnectionTimeoutException) { zend_class_entry ce; (void)type;(void)module_number; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver\\Exception", "ConnectionTimeoutException", php_phongo_connectiontimeoutexception_me); #if PHP_VERSION_ID >= 70000 php_phongo_connectiontimeoutexception_ce = zend_register_internal_class_ex(&ce, php_phongo_connectionexception_ce); #else php_phongo_connectiontimeoutexception_ce = zend_register_internal_class_ex(&ce, php_phongo_connectionexception_ce, NULL TSRMLS_CC); #endif PHONGO_CE_INIT(php_phongo_connectiontimeoutexception_ce); return SUCCESS; } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mongodb-1.1.5/src/MongoDB/Exception/Exception.c0000664000175000017500000000503312673034026021123 0ustar jmikolajmikola/* +---------------------------------------------------------------------------+ | PHP Driver for MongoDB | +---------------------------------------------------------------------------+ | Copyright 2013-2015 MongoDB, Inc. | | | | Licensed under the Apache License, Version 2.0 (the "License"); | | you may not use this file except in compliance with the License. | | You may obtain a copy of the License at | | | | http://www.apache.org/licenses/LICENSE-2.0 | | | | Unless required by applicable law or agreed to in writing, software | | distributed under the License is distributed on an "AS IS" BASIS, | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | See the License for the specific language governing permissions and | | limitations under the License. | +---------------------------------------------------------------------------+ | Copyright (c) 2014-2015 MongoDB, Inc. | +---------------------------------------------------------------------------+ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif /* External libs */ #include #include /* PHP Core stuff */ #include #include #include #include #include /* Our Compatability header */ #include "phongo_compat.h" /* Our stuffz */ #include "php_phongo.h" #include "php_bson.h" #include PHONGO_API zend_class_entry *php_phongo_exception_ce; /* {{{ MongoDB\Driver\Exception */ static zend_function_entry php_phongo_exception_me[] = { PHP_FE_END }; /* }}} */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(Exception) { zend_class_entry ce; (void)type;(void)module_number; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver\\Exception", "Exception", php_phongo_exception_me); php_phongo_exception_ce = zend_register_internal_interface(&ce TSRMLS_CC); return SUCCESS; } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mongodb-1.1.5/src/MongoDB/Exception/ExecutionTimeoutException.c0000664000175000017500000000560412673034026024362 0ustar jmikolajmikola/* +---------------------------------------------------------------------------+ | PHP Driver for MongoDB | +---------------------------------------------------------------------------+ | Copyright 2013-2015 MongoDB, Inc. | | | | Licensed under the Apache License, Version 2.0 (the "License"); | | you may not use this file except in compliance with the License. | | You may obtain a copy of the License at | | | | http://www.apache.org/licenses/LICENSE-2.0 | | | | Unless required by applicable law or agreed to in writing, software | | distributed under the License is distributed on an "AS IS" BASIS, | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | See the License for the specific language governing permissions and | | limitations under the License. | +---------------------------------------------------------------------------+ | Copyright (c) 2014-2015 MongoDB, Inc. | +---------------------------------------------------------------------------+ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif /* External libs */ #include #include /* PHP Core stuff */ #include #include #include #include #include /* Our Compatability header */ #include "phongo_compat.h" /* Our stuffz */ #include "php_phongo.h" #include "php_bson.h" #include PHONGO_API zend_class_entry *php_phongo_executiontimeoutexception_ce; /* {{{ MongoDB\Driver\ExecutionTimeoutException */ static zend_function_entry php_phongo_executiontimeoutexception_me[] = { PHP_FE_END }; /* }}} */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(ExecutionTimeoutException) { zend_class_entry ce; (void)type;(void)module_number; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver\\Exception", "ExecutionTimeoutException", php_phongo_executiontimeoutexception_me); #if PHP_VERSION_ID >= 70000 php_phongo_executiontimeoutexception_ce = zend_register_internal_class_ex(&ce, php_phongo_runtimeexception_ce); #else php_phongo_executiontimeoutexception_ce = zend_register_internal_class_ex(&ce, php_phongo_runtimeexception_ce, NULL TSRMLS_CC); #endif PHONGO_CE_INIT(php_phongo_executiontimeoutexception_ce); return SUCCESS; } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mongodb-1.1.5/src/MongoDB/Exception/InvalidArgumentException.c0000664000175000017500000000566112673034026024144 0ustar jmikolajmikola/* +---------------------------------------------------------------------------+ | PHP Driver for MongoDB | +---------------------------------------------------------------------------+ | Copyright 2013-2015 MongoDB, Inc. | | | | Licensed under the Apache License, Version 2.0 (the "License"); | | you may not use this file except in compliance with the License. | | You may obtain a copy of the License at | | | | http://www.apache.org/licenses/LICENSE-2.0 | | | | Unless required by applicable law or agreed to in writing, software | | distributed under the License is distributed on an "AS IS" BASIS, | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | See the License for the specific language governing permissions and | | limitations under the License. | +---------------------------------------------------------------------------+ | Copyright (c) 2014-2015 MongoDB, Inc. | +---------------------------------------------------------------------------+ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif /* External libs */ #include #include /* PHP Core stuff */ #include #include #include #include #include /* Our Compatability header */ #include "phongo_compat.h" /* Our stuffz */ #include "php_phongo.h" #include "php_bson.h" #include PHONGO_API zend_class_entry *php_phongo_invalidargumentexception_ce; /* {{{ MongoDB\Driver\InvalidArgumentException */ static zend_function_entry php_phongo_invalidargumentexception_me[] = { PHP_FE_END }; /* }}} */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(InvalidArgumentException) { zend_class_entry ce; (void)type;(void)module_number; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver\\Exception", "InvalidArgumentException", php_phongo_invalidargumentexception_me); #if PHP_VERSION_ID >= 70000 php_phongo_invalidargumentexception_ce = zend_register_internal_class_ex(&ce, spl_ce_InvalidArgumentException); #else php_phongo_invalidargumentexception_ce = zend_register_internal_class_ex(&ce, spl_ce_InvalidArgumentException, NULL TSRMLS_CC); #endif zend_class_implements(php_phongo_invalidargumentexception_ce TSRMLS_CC, 1, php_phongo_exception_ce); return SUCCESS; } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mongodb-1.1.5/src/MongoDB/Exception/LogicException.c0000664000175000017500000000550312673034026022103 0ustar jmikolajmikola/* +---------------------------------------------------------------------------+ | PHP Driver for MongoDB | +---------------------------------------------------------------------------+ | Copyright 2013-2015 MongoDB, Inc. | | | | Licensed under the Apache License, Version 2.0 (the "License"); | | you may not use this file except in compliance with the License. | | You may obtain a copy of the License at | | | | http://www.apache.org/licenses/LICENSE-2.0 | | | | Unless required by applicable law or agreed to in writing, software | | distributed under the License is distributed on an "AS IS" BASIS, | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | See the License for the specific language governing permissions and | | limitations under the License. | +---------------------------------------------------------------------------+ | Copyright (c) 2014-2015 MongoDB, Inc. | +---------------------------------------------------------------------------+ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif /* External libs */ #include #include /* PHP Core stuff */ #include #include #include #include #include /* Our Compatability header */ #include "phongo_compat.h" /* Our stuffz */ #include "php_phongo.h" #include "php_bson.h" #include PHONGO_API zend_class_entry *php_phongo_logicexception_ce; /* {{{ MongoDB\Driver\LogicException */ static zend_function_entry php_phongo_logicexception_me[] = { PHP_FE_END }; /* }}} */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(LogicException) { zend_class_entry ce; (void)type;(void)module_number; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver\\Exception", "LogicException", php_phongo_logicexception_me); #if PHP_VERSION_ID >= 70000 php_phongo_logicexception_ce = zend_register_internal_class_ex(&ce, spl_ce_LogicException); #else php_phongo_logicexception_ce = zend_register_internal_class_ex(&ce, spl_ce_LogicException, NULL TSRMLS_CC); #endif zend_class_implements(php_phongo_logicexception_ce TSRMLS_CC, 1, php_phongo_exception_ce); return SUCCESS; } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mongodb-1.1.5/src/MongoDB/Exception/RuntimeException.c0000664000175000017500000000553112673034026022472 0ustar jmikolajmikola/* +---------------------------------------------------------------------------+ | PHP Driver for MongoDB | +---------------------------------------------------------------------------+ | Copyright 2013-2015 MongoDB, Inc. | | | | Licensed under the Apache License, Version 2.0 (the "License"); | | you may not use this file except in compliance with the License. | | You may obtain a copy of the License at | | | | http://www.apache.org/licenses/LICENSE-2.0 | | | | Unless required by applicable law or agreed to in writing, software | | distributed under the License is distributed on an "AS IS" BASIS, | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | See the License for the specific language governing permissions and | | limitations under the License. | +---------------------------------------------------------------------------+ | Copyright (c) 2014-2015 MongoDB, Inc. | +---------------------------------------------------------------------------+ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif /* External libs */ #include #include /* PHP Core stuff */ #include #include #include #include #include /* Our Compatability header */ #include "phongo_compat.h" /* Our stuffz */ #include "php_phongo.h" #include "php_bson.h" #include PHONGO_API zend_class_entry *php_phongo_runtimeexception_ce; /* {{{ MongoDB\Driver\RuntimeException */ static zend_function_entry php_phongo_runtimeexception_me[] = { PHP_FE_END }; /* }}} */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(RuntimeException) { zend_class_entry ce; (void)type;(void)module_number; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver\\Exception", "RuntimeException", php_phongo_runtimeexception_me); #if PHP_VERSION_ID >= 70000 php_phongo_runtimeexception_ce = zend_register_internal_class_ex(&ce, spl_ce_RuntimeException); #else php_phongo_runtimeexception_ce = zend_register_internal_class_ex(&ce, spl_ce_RuntimeException, NULL TSRMLS_CC); #endif zend_class_implements(php_phongo_runtimeexception_ce TSRMLS_CC, 1, php_phongo_exception_ce); return SUCCESS; } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mongodb-1.1.5/src/MongoDB/Exception/SSLConnectionException.c0000664000175000017500000000555712673034026023540 0ustar jmikolajmikola/* +---------------------------------------------------------------------------+ | PHP Driver for MongoDB | +---------------------------------------------------------------------------+ | Copyright 2013-2015 MongoDB, Inc. | | | | Licensed under the Apache License, Version 2.0 (the "License"); | | you may not use this file except in compliance with the License. | | You may obtain a copy of the License at | | | | http://www.apache.org/licenses/LICENSE-2.0 | | | | Unless required by applicable law or agreed to in writing, software | | distributed under the License is distributed on an "AS IS" BASIS, | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | See the License for the specific language governing permissions and | | limitations under the License. | +---------------------------------------------------------------------------+ | Copyright (c) 2014-2015 MongoDB, Inc. | +---------------------------------------------------------------------------+ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif /* External libs */ #include #include /* PHP Core stuff */ #include #include #include #include #include /* Our Compatability header */ #include "phongo_compat.h" /* Our stuffz */ #include "php_phongo.h" #include "php_bson.h" #include PHONGO_API zend_class_entry *php_phongo_sslconnectionexception_ce; /* {{{ MongoDB\Driver\SSLConnectionException */ static zend_function_entry php_phongo_sslconnectionexception_me[] = { PHP_FE_END }; /* }}} */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(SSLConnectionException) { zend_class_entry ce; (void)type;(void)module_number; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver\\Exception", "SSLConnectionException", php_phongo_sslconnectionexception_me); #if PHP_VERSION_ID >= 70000 php_phongo_sslconnectionexception_ce = zend_register_internal_class_ex(&ce, php_phongo_connectionexception_ce); #else php_phongo_sslconnectionexception_ce = zend_register_internal_class_ex(&ce, php_phongo_connectionexception_ce, NULL TSRMLS_CC); #endif PHONGO_CE_INIT(php_phongo_sslconnectionexception_ce); return SUCCESS; } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mongodb-1.1.5/src/MongoDB/Exception/UnexpectedValueException.c0000664000175000017500000000566112673034026024154 0ustar jmikolajmikola/* +---------------------------------------------------------------------------+ | PHP Driver for MongoDB | +---------------------------------------------------------------------------+ | Copyright 2013-2015 MongoDB, Inc. | | | | Licensed under the Apache License, Version 2.0 (the "License"); | | you may not use this file except in compliance with the License. | | You may obtain a copy of the License at | | | | http://www.apache.org/licenses/LICENSE-2.0 | | | | Unless required by applicable law or agreed to in writing, software | | distributed under the License is distributed on an "AS IS" BASIS, | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | See the License for the specific language governing permissions and | | limitations under the License. | +---------------------------------------------------------------------------+ | Copyright (c) 2014-2015 MongoDB, Inc. | +---------------------------------------------------------------------------+ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif /* External libs */ #include #include /* PHP Core stuff */ #include #include #include #include #include /* Our Compatability header */ #include "phongo_compat.h" /* Our stuffz */ #include "php_phongo.h" #include "php_bson.h" #include PHONGO_API zend_class_entry *php_phongo_unexpectedvalueexception_ce; /* {{{ MongoDB\Driver\UnexpectedValueException */ static zend_function_entry php_phongo_unexpectedvalueexception_me[] = { PHP_FE_END }; /* }}} */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(UnexpectedValueException) { zend_class_entry ce; (void)type;(void)module_number; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver\\Exception", "UnexpectedValueException", php_phongo_unexpectedvalueexception_me); #if PHP_VERSION_ID >= 70000 php_phongo_unexpectedvalueexception_ce = zend_register_internal_class_ex(&ce, spl_ce_UnexpectedValueException); #else php_phongo_unexpectedvalueexception_ce = zend_register_internal_class_ex(&ce, spl_ce_UnexpectedValueException, NULL TSRMLS_CC); #endif zend_class_implements(php_phongo_unexpectedvalueexception_ce TSRMLS_CC, 1, php_phongo_exception_ce); return SUCCESS; } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mongodb-1.1.5/src/MongoDB/Exception/WriteException.c0000664000175000017500000000747412673034026022151 0ustar jmikolajmikola/* +---------------------------------------------------------------------------+ | PHP Driver for MongoDB | +---------------------------------------------------------------------------+ | Copyright 2013-2015 MongoDB, Inc. | | | | Licensed under the Apache License, Version 2.0 (the "License"); | | you may not use this file except in compliance with the License. | | You may obtain a copy of the License at | | | | http://www.apache.org/licenses/LICENSE-2.0 | | | | Unless required by applicable law or agreed to in writing, software | | distributed under the License is distributed on an "AS IS" BASIS, | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | See the License for the specific language governing permissions and | | limitations under the License. | +---------------------------------------------------------------------------+ | Copyright (c) 2014-2015 MongoDB, Inc. | +---------------------------------------------------------------------------+ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif /* External libs */ #include #include /* PHP Core stuff */ #include #include #include #include #include /* Our Compatability header */ #include "phongo_compat.h" /* Our stuffz */ #include "php_phongo.h" #include "php_bson.h" #include PHONGO_API zend_class_entry *php_phongo_writeexception_ce; /* {{{ proto MongoDB\Driver\WriteResult WriteException::getWriteResult() Returns the WriteResult from the failed write operation. */ PHP_METHOD(WriteException, getWriteResult) { zval *writeresult; #if PHP_VERSION_ID >= 70000 zval rv; #endif if (zend_parse_parameters_none() == FAILURE) { return; } #if PHP_VERSION_ID >= 70000 writeresult = zend_read_property(php_phongo_writeexception_ce, getThis(), ZEND_STRL("writeResult"), 0, &rv TSRMLS_CC); #else writeresult = zend_read_property(php_phongo_writeexception_ce, getThis(), ZEND_STRL("writeResult"), 0 TSRMLS_CC); #endif RETURN_ZVAL(writeresult, 1, 0); } /* }}} */ /** * Value object for write concern used in issuing write operations. */ /* {{{ MongoDB\Driver\WriteException */ ZEND_BEGIN_ARG_INFO_EX(ai_WriteException_getWriteResult, 0, 0, 0) ZEND_END_ARG_INFO(); static zend_function_entry php_phongo_writeexception_me[] = { PHP_ME(WriteException, getWriteResult, ai_WriteException_getWriteResult, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_FE_END }; /* }}} */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(WriteException) { zend_class_entry ce; (void)type;(void)module_number; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver\\Exception", "WriteException", php_phongo_writeexception_me); #if PHP_VERSION_ID >= 70000 php_phongo_writeexception_ce = zend_register_internal_class_ex(&ce, php_phongo_runtimeexception_ce); #else php_phongo_writeexception_ce = zend_register_internal_class_ex(&ce, php_phongo_runtimeexception_ce, NULL TSRMLS_CC); #endif php_phongo_writeexception_ce->ce_flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS; zend_declare_property_null(php_phongo_writeexception_ce, ZEND_STRL("writeResult"), ZEND_ACC_PROTECTED TSRMLS_CC); return SUCCESS; } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mongodb-1.1.5/src/MongoDB/BulkWrite.c0000664000175000017500000003016212673034026017140 0ustar jmikolajmikola/* +---------------------------------------------------------------------------+ | PHP Driver for MongoDB | +---------------------------------------------------------------------------+ | Copyright 2013-2015 MongoDB, Inc. | | | | Licensed under the Apache License, Version 2.0 (the "License"); | | you may not use this file except in compliance with the License. | | You may obtain a copy of the License at | | | | http://www.apache.org/licenses/LICENSE-2.0 | | | | Unless required by applicable law or agreed to in writing, software | | distributed under the License is distributed on an "AS IS" BASIS, | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | See the License for the specific language governing permissions and | | limitations under the License. | +---------------------------------------------------------------------------+ | Copyright (c) 2014-2015 MongoDB, Inc. | +---------------------------------------------------------------------------+ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif /* External libs */ #include #include /* We need to access the internal bulk structure to access the bulk op count */ #include /* PHP Core stuff */ #include #include #include #include #include /* PHP array helpers */ #include "php_array_api.h" /* Our Compatability header */ #include "phongo_compat.h" /* Our stuffz */ #include "php_phongo.h" #include "php_bson.h" PHONGO_API zend_class_entry *php_phongo_bulkwrite_ce; zend_object_handlers php_phongo_handler_bulkwrite; /* {{{ proto MongoDB\Driver\BulkWrite BulkWrite::__construct([array $options = array()]) Constructs a new BulkWrite */ PHP_METHOD(BulkWrite, __construct) { php_phongo_bulkwrite_t *intern; zend_error_handling error_handling; zval *options = NULL; zend_bool ordered = 1; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value) SUPPRESS_UNUSED_WARNING(return_value_used) zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC); intern = Z_BULKWRITE_OBJ_P(getThis()); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!", &options) == FAILURE) { zend_restore_error_handling(&error_handling TSRMLS_CC); return; } zend_restore_error_handling(&error_handling TSRMLS_CC); if (options && php_array_exists(options, "ordered")) { ordered = php_array_fetch_bool(options, "ordered"); } intern->bulk = phongo_bulkwrite_init(ordered); if (options && php_array_exists(options, "bypassDocumentValidation")) { mongoc_bulk_operation_set_bypass_document_validation(intern->bulk, php_array_fetch_bool(options, "bypassDocumentValidation")); } } /* }}} */ /* {{{ proto mixed BulkWrite::insert(array|object $document) Adds an insert operation to the bulk */ PHP_METHOD(BulkWrite, insert) { php_phongo_bulkwrite_t *intern; zval *document; bson_t *bson; bson_t *bson_out = NULL; int bson_flags = PHONGO_BSON_ADD_ID; DECLARE_RETURN_VALUE_USED SUPPRESS_UNUSED_WARNING(return_value_ptr) intern = Z_BULKWRITE_OBJ_P(getThis()); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "A", &document) == FAILURE) { return; } if (return_value_used) { bson_flags |= PHONGO_BSON_RETURN_ID; } bson = bson_new(); phongo_zval_to_bson(document, bson_flags, bson, &bson_out TSRMLS_CC); mongoc_bulk_operation_insert(intern->bulk, bson); bson_clear(&bson); if (bson_out && return_value_used) { bson_iter_t iter; if (bson_iter_init_find(&iter, bson_out, "_id")) { php_phongo_objectid_new_from_oid(return_value, bson_iter_oid(&iter) TSRMLS_CC); bson_clear(&bson_out); return; } bson_clear(&bson_out); } } /* }}} */ /* {{{ proto void BulkWrite::update(array|object $query, array|object $newObj[, array $updateOptions = array()]) Adds an update operation to bulk */ PHP_METHOD(BulkWrite, update) { php_phongo_bulkwrite_t *intern; zval *query; zval *newObj; zval *updateOptions = NULL; mongoc_update_flags_t flags = MONGOC_UPDATE_NONE; bson_t *bquery; bson_t *bupdate; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_BULKWRITE_OBJ_P(getThis()); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "AA|a!", &query, &newObj, &updateOptions) == FAILURE) { return; } bquery = bson_new(); bupdate = bson_new(); phongo_zval_to_bson(query, PHONGO_BSON_NONE, bquery, NULL TSRMLS_CC); phongo_zval_to_bson(newObj, PHONGO_BSON_NONE, bupdate, NULL TSRMLS_CC); if (updateOptions) { flags |= php_array_fetch_bool(updateOptions, "multi") ? MONGOC_UPDATE_MULTI_UPDATE : 0; flags |= php_array_fetch_bool(updateOptions, "upsert") ? MONGOC_UPDATE_UPSERT : 0; } if (flags & MONGOC_UPDATE_MULTI_UPDATE) { mongoc_bulk_operation_update(intern->bulk, bquery, bupdate, !!(flags & MONGOC_UPDATE_UPSERT)); } else { bson_iter_t iter; zend_bool replaced = 0; if (bson_iter_init(&iter, bupdate)) { while (bson_iter_next (&iter)) { if (!strchr (bson_iter_key (&iter), '$')) { mongoc_bulk_operation_replace_one(intern->bulk, bquery, bupdate, !!(flags & MONGOC_UPDATE_UPSERT)); replaced = 1; break; } } } if (!replaced) { mongoc_bulk_operation_update_one(intern->bulk, bquery, bupdate, !!(flags & MONGOC_UPDATE_UPSERT)); } } bson_clear(&bquery); bson_clear(&bupdate); } /* }}} */ /* {{{ proto void BulkWrite::delete(array|object $query[, array $deleteOptions = array()]) Adds a delete operation to the bulk */ PHP_METHOD(BulkWrite, delete) { php_phongo_bulkwrite_t *intern; zval *query; zval *deleteOptions = NULL; bson_t *bson; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_BULKWRITE_OBJ_P(getThis()); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "A|a!", &query, &deleteOptions) == FAILURE) { return; } bson = bson_new(); phongo_zval_to_bson(query, PHONGO_BSON_NONE, bson, NULL TSRMLS_CC); if (deleteOptions && php_array_fetch_bool(deleteOptions, "limit")) { mongoc_bulk_operation_remove_one(intern->bulk, bson); } else { mongoc_bulk_operation_remove(intern->bulk, bson); } bson_clear(&bson); } /* }}} */ /* {{{ proto integer BulkWrite::count() Returns the number of operations that have been added to the bulk */ PHP_METHOD(BulkWrite, count) { php_phongo_bulkwrite_t *intern; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_BULKWRITE_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } RETURN_LONG(intern->bulk->commands.len); } /* }}} */ /* {{{ MongoDB\Driver\BulkWrite */ ZEND_BEGIN_ARG_INFO_EX(ai_BulkWrite___construct, 0, 0, 0) ZEND_ARG_ARRAY_INFO(0, options, 1) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_BulkWrite_insert, 0, 0, 1) ZEND_ARG_INFO(0, document) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_BulkWrite_update, 0, 0, 2) ZEND_ARG_INFO(0, query) ZEND_ARG_INFO(0, newObj) ZEND_ARG_ARRAY_INFO(0, updateOptions, 1) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_BulkWrite_delete, 0, 0, 1) ZEND_ARG_INFO(0, query) ZEND_ARG_ARRAY_INFO(0, deleteOptions, 1) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_BulkWrite_count, 0, 0, 0) ZEND_END_ARG_INFO(); static zend_function_entry php_phongo_bulkwrite_me[] = { PHP_ME(BulkWrite, __construct, ai_BulkWrite___construct, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(BulkWrite, insert, ai_BulkWrite_insert, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(BulkWrite, update, ai_BulkWrite_update, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(BulkWrite, delete, ai_BulkWrite_delete, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(BulkWrite, count, ai_BulkWrite_count, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Manager, __wakeUp, NULL, ZEND_ACC_PUBLIC) PHP_FE_END }; /* }}} */ /* {{{ php_phongo_bulkwrite_t object handlers */ static void php_phongo_bulkwrite_free_object(phongo_free_object_arg *object TSRMLS_DC) /* {{{ */ { php_phongo_bulkwrite_t *intern = Z_OBJ_BULKWRITE(object); zend_object_std_dtor(&intern->std TSRMLS_CC); if (intern->bulk) { mongoc_bulk_operation_destroy(intern->bulk); } #if PHP_VERSION_ID < 70000 efree(intern); #endif } /* }}} */ phongo_create_object_retval php_phongo_bulkwrite_create_object(zend_class_entry *class_type TSRMLS_DC) /* {{{ */ { php_phongo_bulkwrite_t *intern = NULL; intern = PHONGO_ALLOC_OBJECT_T(php_phongo_bulkwrite_t, class_type); zend_object_std_init(&intern->std, class_type TSRMLS_CC); object_properties_init(&intern->std, class_type); #if PHP_VERSION_ID >= 70000 intern->std.handlers = &php_phongo_handler_bulkwrite; return &intern->std; #else { zend_object_value retval; retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_bulkwrite_free_object, NULL TSRMLS_CC); retval.handlers = &php_phongo_handler_bulkwrite; return retval; } #endif } /* }}} */ HashTable *php_phongo_bulkwrite_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */ { #if PHP_VERSION_ID >= 70000 zval retval; #else zval retval = zval_used_for_init; #endif php_phongo_bulkwrite_t *intern = NULL; *is_temp = 1; intern = Z_BULKWRITE_OBJ_P(object); array_init(&retval); if (intern->bulk->database) { ADD_ASSOC_STRING(&retval, "database", intern->bulk->database); } else { ADD_ASSOC_NULL_EX(&retval, "database"); } if (intern->bulk->collection) { ADD_ASSOC_STRING(&retval, "collection", intern->bulk->collection); } else { ADD_ASSOC_NULL_EX(&retval, "collection"); } ADD_ASSOC_BOOL_EX(&retval, "ordered", intern->bulk->flags.ordered); ADD_ASSOC_BOOL_EX(&retval, "executed", intern->bulk->executed); ADD_ASSOC_LONG_EX(&retval, "server_id", intern->bulk->hint); if (intern->bulk->write_concern) { #if PHP_VERSION_ID >= 70000 zval write_concern; php_phongo_write_concern_to_zval(&write_concern, intern->bulk->write_concern); ADD_ASSOC_ZVAL_EX(&retval, "write_concern", &write_concern); #else zval *write_concern = NULL; MAKE_STD_ZVAL(write_concern); php_phongo_write_concern_to_zval(write_concern, intern->bulk->write_concern); ADD_ASSOC_ZVAL_EX(&retval, "write_concern", write_concern); #endif } else { ADD_ASSOC_NULL_EX(&retval, "write_concern"); } return Z_ARRVAL(retval); } /* }}} */ /* }}} */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(BulkWrite) { zend_class_entry ce; (void)type;(void)module_number; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver", "BulkWrite", php_phongo_bulkwrite_me); php_phongo_bulkwrite_ce = zend_register_internal_class(&ce TSRMLS_CC); php_phongo_bulkwrite_ce->create_object = php_phongo_bulkwrite_create_object; PHONGO_CE_INIT(php_phongo_bulkwrite_ce); memcpy(&php_phongo_handler_bulkwrite, phongo_get_std_object_handlers(), sizeof(zend_object_handlers)); php_phongo_handler_bulkwrite.get_debug_info = php_phongo_bulkwrite_get_debug_info; #if PHP_VERSION_ID >= 70000 php_phongo_handler_bulkwrite.free_obj = php_phongo_bulkwrite_free_object; php_phongo_handler_bulkwrite.offset = XtOffsetOf(php_phongo_bulkwrite_t, std); #endif zend_class_implements(php_phongo_bulkwrite_ce TSRMLS_CC, 1, spl_ce_Countable); return SUCCESS; } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mongodb-1.1.5/src/MongoDB/Command.c0000664000175000017500000001372512673034026016614 0ustar jmikolajmikola/* +---------------------------------------------------------------------------+ | PHP Driver for MongoDB | +---------------------------------------------------------------------------+ | Copyright 2013-2015 MongoDB, Inc. | | | | Licensed under the Apache License, Version 2.0 (the "License"); | | you may not use this file except in compliance with the License. | | You may obtain a copy of the License at | | | | http://www.apache.org/licenses/LICENSE-2.0 | | | | Unless required by applicable law or agreed to in writing, software | | distributed under the License is distributed on an "AS IS" BASIS, | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | See the License for the specific language governing permissions and | | limitations under the License. | +---------------------------------------------------------------------------+ | Copyright (c) 2014-2015 MongoDB, Inc. | +---------------------------------------------------------------------------+ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif /* External libs */ #include #include /* PHP Core stuff */ #include #include #include #include #include /* Our Compatability header */ #include "phongo_compat.h" /* Our stuffz */ #include "php_phongo.h" #include "php_bson.h" PHONGO_API zend_class_entry *php_phongo_command_ce; zend_object_handlers php_phongo_handler_command; /* {{{ proto MongoDB\Driver\Command Command::__construct(array|object $document) Constructs a new Command */ PHP_METHOD(Command, __construct) { php_phongo_command_t *intern; zend_error_handling error_handling; zval *document; bson_t *bson = bson_new(); SUPPRESS_UNUSED_WARNING(return_value) SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC); intern = Z_COMMAND_OBJ_P(getThis()); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "A", &document) == FAILURE) { zend_restore_error_handling(&error_handling TSRMLS_CC); return; } zend_restore_error_handling(&error_handling TSRMLS_CC); phongo_zval_to_bson(document, PHONGO_BSON_NONE, bson, NULL TSRMLS_CC); intern->bson = bson; } /* }}} */ /** * Value object for a database command document. */ /* {{{ MongoDB\Driver\Command */ ZEND_BEGIN_ARG_INFO_EX(ai_Command___construct, 0, 0, 1) ZEND_ARG_INFO(0, document) ZEND_END_ARG_INFO(); static zend_function_entry php_phongo_command_me[] = { PHP_ME(Command, __construct, ai_Command___construct, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Manager, __wakeUp, NULL, ZEND_ACC_PUBLIC) PHP_FE_END }; /* }}} */ /* {{{ php_phongo_command_t object handlers */ static void php_phongo_command_free_object(phongo_free_object_arg *object TSRMLS_DC) /* {{{ */ { php_phongo_command_t *intern = Z_OBJ_COMMAND(object); zend_object_std_dtor(&intern->std TSRMLS_CC); if (intern->bson) { bson_clear(&intern->bson); } #if PHP_VERSION_ID < 70000 efree(intern); #endif } /* }}} */ phongo_create_object_retval php_phongo_command_create_object(zend_class_entry *class_type TSRMLS_DC) /* {{{ */ { php_phongo_command_t *intern = NULL; intern = PHONGO_ALLOC_OBJECT_T(php_phongo_command_t, class_type); zend_object_std_init(&intern->std, class_type TSRMLS_CC); object_properties_init(&intern->std, class_type); #if PHP_VERSION_ID >= 70000 intern->std.handlers = &php_phongo_handler_command; return &intern->std; #else { zend_object_value retval; retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_command_free_object, NULL TSRMLS_CC); retval.handlers = &php_phongo_handler_command; return retval; } #endif } /* }}} */ HashTable *php_phongo_command_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */ { php_phongo_command_t *intern; #if PHP_VERSION_ID >= 70000 zval retval; #else zval retval = zval_used_for_init; #endif *is_temp = 1; intern = Z_COMMAND_OBJ_P(object); array_init_size(&retval, 1); if (intern->bson) { #if PHP_VERSION_ID >= 70000 zval zv; #else zval *zv; #endif phongo_bson_to_zval(bson_get_data(intern->bson), intern->bson->len, &zv); #if PHP_VERSION_ID >= 70000 ADD_ASSOC_ZVAL_EX(&retval, "command", &zv); #else ADD_ASSOC_ZVAL_EX(&retval, "command", zv); #endif } else { ADD_ASSOC_NULL_EX(&retval, "command"); } return Z_ARRVAL(retval); } /* }}} */ /* }}} */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(Command) { zend_class_entry ce; (void)type;(void)module_number; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver", "Command", php_phongo_command_me); php_phongo_command_ce = zend_register_internal_class(&ce TSRMLS_CC); php_phongo_command_ce->create_object = php_phongo_command_create_object; PHONGO_CE_INIT(php_phongo_command_ce); memcpy(&php_phongo_handler_command, phongo_get_std_object_handlers(), sizeof(zend_object_handlers)); php_phongo_handler_command.get_debug_info = php_phongo_command_get_debug_info; #if PHP_VERSION_ID >= 70000 php_phongo_handler_command.free_obj = php_phongo_command_free_object; php_phongo_handler_command.offset = XtOffsetOf(php_phongo_command_t, std); #endif return SUCCESS; } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mongodb-1.1.5/src/MongoDB/Cursor.c0000664000175000017500000002212212673034026016502 0ustar jmikolajmikola/* +---------------------------------------------------------------------------+ | PHP Driver for MongoDB | +---------------------------------------------------------------------------+ | Copyright 2013-2015 MongoDB, Inc. | | | | Licensed under the Apache License, Version 2.0 (the "License"); | | you may not use this file except in compliance with the License. | | You may obtain a copy of the License at | | | | http://www.apache.org/licenses/LICENSE-2.0 | | | | Unless required by applicable law or agreed to in writing, software | | distributed under the License is distributed on an "AS IS" BASIS, | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | See the License for the specific language governing permissions and | | limitations under the License. | +---------------------------------------------------------------------------+ | Copyright (c) 2014-2015 MongoDB, Inc. | +---------------------------------------------------------------------------+ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif /* External libs */ #include #include #include #include /* PHP Core stuff */ #include #include #include #include #include /* Our Compatability header */ #include "phongo_compat.h" /* Our stuffz */ #include "php_phongo.h" #include "php_bson.h" PHONGO_API zend_class_entry *php_phongo_cursor_ce; zend_object_handlers php_phongo_handler_cursor; /* {{{ proto void Cursor::setTypeMap(array $typemap) Sets a type map to use for BSON unserialization */ PHP_METHOD(Cursor, setTypeMap) { php_phongo_cursor_t *intern; php_phongo_bson_state state = PHONGO_BSON_STATE_INITIALIZER; zval *typemap = NULL; SUPPRESS_UNUSED_WARNING(return_value) SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_CURSOR_OBJ_P(getThis()); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a!", &typemap) == FAILURE) { return; } phongo_bson_typemap_to_state(typemap, &state.map TSRMLS_CC); intern->visitor_data = state; } /* }}} */ static int php_phongo_cursor_to_array_apply(zend_object_iterator *iter, void *puser TSRMLS_DC) /* {{{ */ { #if PHP_VERSION_ID >= 70000 zval *data; zval *return_value = (zval*)puser; data = iter->funcs->get_current_data(iter TSRMLS_CC); if (EG(exception)) { return ZEND_HASH_APPLY_STOP; } if (Z_ISUNDEF_P(data)) { return ZEND_HASH_APPLY_STOP; } Z_TRY_ADDREF_P(data); add_next_index_zval(return_value, data); #else zval **data; zval *return_value = (zval*)puser; iter->funcs->get_current_data(iter, &data TSRMLS_CC); if (EG(exception)) { return ZEND_HASH_APPLY_STOP; } if (data == NULL || *data == NULL) { return ZEND_HASH_APPLY_STOP; } Z_ADDREF_PP(data); add_next_index_zval(return_value, *data); #endif return ZEND_HASH_APPLY_KEEP; } /* }}} */ /* {{{ proto array Cursor::toArray() Returns an array of all result documents for this cursor */ PHP_METHOD(Cursor, toArray) { SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) if (zend_parse_parameters_none() == FAILURE) { return; } array_init(return_value); if (spl_iterator_apply(getThis(), php_phongo_cursor_to_array_apply, (void*)return_value TSRMLS_CC) != SUCCESS) { zval_dtor(return_value); RETURN_NULL(); } } /* }}} */ /* {{{ proto MongoDB\Driver\CursorId Cursor::getId() Returns the CursorId for this cursor */ PHP_METHOD(Cursor, getId) { php_phongo_cursor_t *intern; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_CURSOR_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } php_phongo_cursor_id_new_from_id(return_value, mongoc_cursor_get_id(intern->cursor) TSRMLS_CC); } /* }}} */ /* {{{ proto MongoDB\Driver\Server Cursor::getServer() Returns the Server object to which this cursor is attached */ PHP_METHOD(Cursor, getServer) { php_phongo_cursor_t *intern; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_CURSOR_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } phongo_server_init(return_value, intern->cursor->client, intern->server_id TSRMLS_CC); } /* }}} */ /* {{{ proto boolean Cursor::isDead() Checks if a cursor is still alive */ PHP_METHOD(Cursor, isDead) { php_phongo_cursor_t *intern; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_CURSOR_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } RETURN_BOOL(!mongoc_cursor_is_alive(intern->cursor)); } /* }}} */ /* {{{ MongoDB\Driver\Cursor */ ZEND_BEGIN_ARG_INFO_EX(ai_Cursor_setTypeMap, 0, 0, 1) ZEND_ARG_ARRAY_INFO(0, typemap, 0) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_Cursor_toArray, 0, 0, 0) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_Cursor_getId, 0, 0, 0) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_Cursor_getServer, 0, 0, 0) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_Cursor_isDead, 0, 0, 0) ZEND_END_ARG_INFO(); static zend_function_entry php_phongo_cursor_me[] = { PHP_ME(Server, __construct, NULL, ZEND_ACC_FINAL|ZEND_ACC_PRIVATE) PHP_ME(Cursor, setTypeMap, ai_Cursor_setTypeMap, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Cursor, toArray, ai_Cursor_toArray, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Cursor, getId, ai_Cursor_getId, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Cursor, getServer, ai_Cursor_getServer, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Cursor, isDead, ai_Cursor_isDead, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Manager, __wakeUp, NULL, ZEND_ACC_PUBLIC) PHP_FE_END }; /* }}} */ /* {{{ php_phongo_cursor_t object handlers */ static void php_phongo_cursor_free_object(phongo_free_object_arg *object TSRMLS_DC) /* {{{ */ { php_phongo_cursor_t *intern = Z_OBJ_CURSOR(object); zend_object_std_dtor(&intern->std TSRMLS_CC); php_phongo_cursor_free(intern); #if PHP_VERSION_ID < 70000 efree(intern); #endif } /* }}} */ phongo_create_object_retval php_phongo_cursor_create_object(zend_class_entry *class_type TSRMLS_DC) /* {{{ */ { php_phongo_cursor_t *intern = NULL; intern = PHONGO_ALLOC_OBJECT_T(php_phongo_cursor_t, class_type); zend_object_std_init(&intern->std, class_type TSRMLS_CC); object_properties_init(&intern->std, class_type); #if PHP_VERSION_ID >= 70000 intern->std.handlers = &php_phongo_handler_cursor; return &intern->std; #else { zend_object_value retval; retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_cursor_free_object, NULL TSRMLS_CC); retval.handlers = &php_phongo_handler_cursor; return retval; } #endif } /* }}} */ HashTable *php_phongo_cursor_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */ { php_phongo_cursor_t *intern; #if PHP_VERSION_ID >= 70000 zval retval; #else zval retval = zval_used_for_init; #endif *is_temp = 1; intern = Z_CURSOR_OBJ_P(object); array_init_size(&retval, 2); if (intern->cursor) { #if PHP_VERSION_ID >= 70000 zval zcursor; php_phongo_cursor_to_zval(&zcursor, intern->cursor); ADD_ASSOC_ZVAL_EX(&retval, "cursor", &zcursor); #else zval *zcursor = NULL; MAKE_STD_ZVAL(zcursor); php_phongo_cursor_to_zval(zcursor, intern->cursor); ADD_ASSOC_ZVAL_EX(&retval, "cursor", zcursor); #endif } else { ADD_ASSOC_NULL_EX(&retval, "cursor"); } ADD_ASSOC_LONG_EX(&retval, "server_id", intern->server_id); return Z_ARRVAL(retval); } /* }}} */ /* }}} */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(Cursor) { zend_class_entry ce; (void)type;(void)module_number; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver", "Cursor", php_phongo_cursor_me); php_phongo_cursor_ce = zend_register_internal_class(&ce TSRMLS_CC); php_phongo_cursor_ce->create_object = php_phongo_cursor_create_object; PHONGO_CE_INIT(php_phongo_cursor_ce); php_phongo_cursor_ce->get_iterator = php_phongo_cursor_get_iterator; memcpy(&php_phongo_handler_cursor, phongo_get_std_object_handlers(), sizeof(zend_object_handlers)); php_phongo_handler_cursor.get_debug_info = php_phongo_cursor_get_debug_info; #if PHP_VERSION_ID >= 70000 php_phongo_handler_cursor.free_obj = php_phongo_cursor_free_object; php_phongo_handler_cursor.offset = XtOffsetOf(php_phongo_cursor_t, std); #endif zend_class_implements(php_phongo_cursor_ce TSRMLS_CC, 1, zend_ce_traversable); return SUCCESS; } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mongodb-1.1.5/src/MongoDB/CursorId.c0000664000175000017500000001220612673034026016761 0ustar jmikolajmikola/* +---------------------------------------------------------------------------+ | PHP Driver for MongoDB | +---------------------------------------------------------------------------+ | Copyright 2013-2015 MongoDB, Inc. | | | | Licensed under the Apache License, Version 2.0 (the "License"); | | you may not use this file except in compliance with the License. | | You may obtain a copy of the License at | | | | http://www.apache.org/licenses/LICENSE-2.0 | | | | Unless required by applicable law or agreed to in writing, software | | distributed under the License is distributed on an "AS IS" BASIS, | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | See the License for the specific language governing permissions and | | limitations under the License. | +---------------------------------------------------------------------------+ | Copyright (c) 2014-2015 MongoDB, Inc. | +---------------------------------------------------------------------------+ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif /* External libs */ #include #include /* PHP Core stuff */ #include #include #include #include #include /* Our Compatability header */ #include "phongo_compat.h" /* Our stuffz */ #include "php_phongo.h" #include "php_bson.h" PHONGO_API zend_class_entry *php_phongo_cursorid_ce; zend_object_handlers php_phongo_handler_cursorid; /* {{{ proto string CursorId::__toString() Returns the string representation of the CursorId */ PHP_METHOD(CursorId, __toString) { php_phongo_cursorid_t *intern; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_CURSORID_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } RETVAL_LONG(intern->id); convert_to_string(return_value); } /* }}} */ /* {{{ MongoDB\Driver\CursorId */ ZEND_BEGIN_ARG_INFO_EX(ai_CursorId___toString, 0, 0, 0) ZEND_END_ARG_INFO(); static zend_function_entry php_phongo_cursorid_me[] = { PHP_ME(Server, __construct, NULL, ZEND_ACC_FINAL|ZEND_ACC_PRIVATE) PHP_ME(CursorId, __toString, ai_CursorId___toString, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Manager, __wakeUp, NULL, ZEND_ACC_PUBLIC) PHP_FE_END }; /* }}} */ /* {{{ php_phongo_cursorid_t object handlers */ static void php_phongo_cursorid_free_object(phongo_free_object_arg *object TSRMLS_DC) /* {{{ */ { php_phongo_cursorid_t *intern = Z_OBJ_CURSORID(object); zend_object_std_dtor(&intern->std TSRMLS_CC); #if PHP_VERSION_ID < 70000 efree(intern); #endif } /* }}} */ phongo_create_object_retval php_phongo_cursorid_create_object(zend_class_entry *class_type TSRMLS_DC) /* {{{ */ { php_phongo_cursorid_t *intern = NULL; intern = PHONGO_ALLOC_OBJECT_T(php_phongo_cursorid_t, class_type); zend_object_std_init(&intern->std, class_type TSRMLS_CC); object_properties_init(&intern->std, class_type); #if PHP_VERSION_ID >= 70000 intern->std.handlers = &php_phongo_handler_cursorid; return &intern->std; #else { zend_object_value retval; retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_cursorid_free_object, NULL TSRMLS_CC); retval.handlers = &php_phongo_handler_cursorid; return retval; } #endif } /* }}} */ HashTable *php_phongo_cursorid_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */ { php_phongo_cursorid_t *intern; #if PHP_VERSION_ID >= 70000 zval retval; #else zval retval = zval_used_for_init; #endif *is_temp = 1; intern = Z_CURSORID_OBJ_P(object); array_init(&retval); ADD_ASSOC_LONG_EX(&retval, "id", intern->id); return Z_ARRVAL(retval); } /* }}} */ /* }}} */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(CursorId) { zend_class_entry ce; (void)type;(void)module_number; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver", "CursorId", php_phongo_cursorid_me); php_phongo_cursorid_ce = zend_register_internal_class(&ce TSRMLS_CC); php_phongo_cursorid_ce->create_object = php_phongo_cursorid_create_object; PHONGO_CE_INIT(php_phongo_cursorid_ce); memcpy(&php_phongo_handler_cursorid, phongo_get_std_object_handlers(), sizeof(zend_object_handlers)); php_phongo_handler_cursorid.get_debug_info = php_phongo_cursorid_get_debug_info; #if PHP_VERSION_ID >= 70000 php_phongo_handler_cursorid.free_obj = php_phongo_cursorid_free_object; php_phongo_handler_cursorid.offset = XtOffsetOf(php_phongo_cursorid_t, std); #endif return SUCCESS; } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mongodb-1.1.5/src/MongoDB/Manager.c0000664000175000017500000004175312673034026016612 0ustar jmikolajmikola/* +---------------------------------------------------------------------------+ | PHP Driver for MongoDB | +---------------------------------------------------------------------------+ | Copyright 2013-2015 MongoDB, Inc. | | | | Licensed under the Apache License, Version 2.0 (the "License"); | | you may not use this file except in compliance with the License. | | You may obtain a copy of the License at | | | | http://www.apache.org/licenses/LICENSE-2.0 | | | | Unless required by applicable law or agreed to in writing, software | | distributed under the License is distributed on an "AS IS" BASIS, | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | See the License for the specific language governing permissions and | | limitations under the License. | +---------------------------------------------------------------------------+ | Copyright (c) 2014-2015 MongoDB, Inc. | +---------------------------------------------------------------------------+ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif /* External libs */ #include #include #include #include #include /* PHP Core stuff */ #include #include #include #include #include #include #include /* PHP array helpers */ #include "php_array_api.h" /* Our Compatability header */ #include "phongo_compat.h" /* Our stuffz */ #include "php_phongo.h" #include "php_bson.h" #define PHONGO_MANAGER_URI_DEFAULT "mongodb://localhost:27017/" PHONGO_API zend_class_entry *php_phongo_manager_ce; zend_object_handlers php_phongo_handler_manager; /* {{{ proto MongoDB\Driver\Manager Manager::__construct([string $uri = "mongodb://localhost:27017/"[, array $options = array()[, array $driverOptions = array()]]]) Constructs a new Manager */ PHP_METHOD(Manager, __construct) { php_phongo_manager_t *intern; zend_error_handling error_handling; char *uri_string = NULL; phongo_zpp_char_len uri_string_len = 0; zval *options = NULL; bson_t bson_options = BSON_INITIALIZER; zval *driverOptions = NULL; SUPPRESS_UNUSED_WARNING(return_value) SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC); intern = Z_MANAGER_OBJ_P(getThis()); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!a!a!", &uri_string, &uri_string_len, &options, &driverOptions) == FAILURE) { zend_restore_error_handling(&error_handling TSRMLS_CC); return; } zend_restore_error_handling(&error_handling TSRMLS_CC); if (options) { phongo_zval_to_bson(options, PHONGO_BSON_NONE, &bson_options, NULL TSRMLS_CC); } phongo_manager_init(intern, uri_string, &bson_options, driverOptions TSRMLS_CC); bson_destroy(&bson_options); } /* }}} */ /* {{{ proto MongoDB\Driver\Cursor Manager::executeCommand(string $db, MongoDB\Driver\Command $command[, MongoDB\Driver\ReadPreference $readPreference = null]) Execute a command */ PHP_METHOD(Manager, executeCommand) { php_phongo_manager_t *intern; char *db; phongo_zpp_char_len db_len; zval *command; zval *readPreference = NULL; php_phongo_command_t *cmd; DECLARE_RETURN_VALUE_USED SUPPRESS_UNUSED_WARNING(return_value_ptr) intern = Z_MANAGER_OBJ_P(getThis()); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sO|O!", &db, &db_len, &command, php_phongo_command_ce, &readPreference, php_phongo_readpreference_ce) == FAILURE) { return; } cmd = Z_COMMAND_OBJ_P(command); phongo_execute_command(intern->client, db, cmd->bson, phongo_read_preference_from_zval(readPreference TSRMLS_CC), -1, return_value, return_value_used TSRMLS_CC); } /* }}} */ /* {{{ proto MongoDB\Driver\Cursor Manager::executeQuery(string $namespace, MongoDB\Driver\Query $zquery[, MongoDB\Driver\ReadPreference $readPreference = null]) Execute a Query */ PHP_METHOD(Manager, executeQuery) { php_phongo_manager_t *intern; char *namespace; phongo_zpp_char_len namespace_len; zval *zquery; zval *readPreference = NULL; DECLARE_RETURN_VALUE_USED SUPPRESS_UNUSED_WARNING(return_value_ptr) intern = Z_MANAGER_OBJ_P(getThis()); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sO|O!", &namespace, &namespace_len, &zquery, php_phongo_query_ce, &readPreference, php_phongo_readpreference_ce) == FAILURE) { return; } phongo_execute_query(intern->client, namespace, phongo_query_from_zval(zquery TSRMLS_CC), phongo_read_preference_from_zval(readPreference TSRMLS_CC), -1, return_value, return_value_used TSRMLS_CC); } /* }}} */ /* {{{ proto MongoDB\Driver\WriteResult Manager::executeBulkWrite(string $namespace, MongoDB\Driver\BulkWrite $zbulk[, MongoDB\Driver\WriteConcern $writeConcern = null]) Executes a write operation bulk (e.g. insert, update, delete) */ PHP_METHOD(Manager, executeBulkWrite) { php_phongo_manager_t *intern; char *namespace; phongo_zpp_char_len namespace_len; zval *zbulk; zval *zwrite_concern = NULL; php_phongo_bulkwrite_t *bulk; DECLARE_RETURN_VALUE_USED SUPPRESS_UNUSED_WARNING(return_value_ptr) intern = Z_MANAGER_OBJ_P(getThis()); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sO|O!", &namespace, &namespace_len, &zbulk, php_phongo_bulkwrite_ce, &zwrite_concern, php_phongo_writeconcern_ce) == FAILURE) { return; } bulk = Z_BULKWRITE_OBJ_P(zbulk); phongo_execute_write(intern->client, namespace, bulk->bulk, phongo_write_concern_from_zval(zwrite_concern TSRMLS_CC), -1, return_value, return_value_used TSRMLS_CC); } /* }}} */ /* {{{ proto MongoDB\Driver\ReadConcern Manager::getReadConcern() Returns the ReadConcern associated with this Manager */ PHP_METHOD(Manager, getReadConcern) { php_phongo_manager_t *intern; DECLARE_RETURN_VALUE_USED SUPPRESS_UNUSED_WARNING(return_value_ptr) intern = Z_MANAGER_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } if (return_value_used) { phongo_readconcern_init(return_value, mongoc_client_get_read_concern(intern->client) TSRMLS_CC); } } /* }}} */ /* {{{ proto MongoDB\Driver\ReadPreference Manager::getReadPreference() Returns the ReadPreference associated with this Manager */ PHP_METHOD(Manager, getReadPreference) { php_phongo_manager_t *intern; DECLARE_RETURN_VALUE_USED SUPPRESS_UNUSED_WARNING(return_value_ptr) intern = Z_MANAGER_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } if (return_value_used) { phongo_readpreference_init(return_value, mongoc_client_get_read_prefs(intern->client) TSRMLS_CC); } } /* }}} */ /* {{{ proto MongoDB\Driver\Server[] Manager::getServers() Returns the Servers associated with this Manager */ PHP_METHOD(Manager, getServers) { php_phongo_manager_t *intern; mongoc_set_t *set; size_t i; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_MANAGER_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } array_init(return_value); set = intern->client->topology->description.servers; for(i=0; iitems_len; i++) { #if PHP_VERSION_ID >= 70000 zval obj; #else zval *obj = NULL; #endif mongoc_server_description_t *sd = (mongoc_server_description_t *) set->items[i].item; if (sd->type == MONGOC_SERVER_UNKNOWN) { continue; } #if PHP_VERSION_ID >= 70000 phongo_server_init(&obj, intern->client, ((mongoc_server_description_t *)set->items[i].item)->id TSRMLS_CC); add_next_index_zval(return_value, &obj); #else MAKE_STD_ZVAL(obj); phongo_server_init(obj, intern->client, sd->id TSRMLS_CC); add_next_index_zval(return_value, obj); #endif } } /* }}} */ /* {{{ proto MongoDB\Driver\WriteConcern Manager::getWriteConcern() Returns the WriteConcern associated with this Manager */ PHP_METHOD(Manager, getWriteConcern) { php_phongo_manager_t *intern; DECLARE_RETURN_VALUE_USED SUPPRESS_UNUSED_WARNING(return_value_ptr) intern = Z_MANAGER_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } if (return_value_used) { phongo_writeconcern_init(return_value, mongoc_client_get_write_concern(intern->client) TSRMLS_CC); } } /* }}} */ /* {{{ proto MongoDB\Driver\Server Manager::selectServers(MongoDB\Driver\ReadPreference $readPreference) Returns a suitable Server for the given $readPreference */ PHP_METHOD(Manager, selectServer) { php_phongo_manager_t *intern; zval *zreadPreference = NULL; const mongoc_read_prefs_t *readPreference; bson_error_t error; mongoc_server_description_t *selected_server = NULL; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_MANAGER_OBJ_P(getThis()); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &zreadPreference, php_phongo_readpreference_ce) == FAILURE) { return; } readPreference = phongo_read_preference_from_zval(zreadPreference TSRMLS_CC); selected_server = mongoc_topology_select(intern->client->topology, MONGOC_SS_READ, readPreference, MONGOC_SS_DEFAULT_LOCAL_THRESHOLD_MS, &error); if (selected_server) { phongo_server_init(return_value, intern->client, selected_server->id TSRMLS_CC); mongoc_server_description_destroy(selected_server); } else { /* Check for connection related exceptions */ if (EG(exception)) { return; } phongo_throw_exception_from_bson_error_t(&error TSRMLS_CC); } } /* }}} */ /* {{{ proto void MongoDB\Driver\Manager::__wakeUp() * Throws MongoDB\Driver\RuntimeException as it cannot be serialized */ PHP_METHOD(Manager, __wakeUp) { SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) SUPPRESS_UNUSED_WARNING(return_value) SUPPRESS_UNUSED_WARNING(this_ptr) if (zend_parse_parameters_none() == FAILURE) { return; } phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "%s", "MongoDB\\Driver objects cannot be serialized"); } /* }}} */ /** * Manager abstracts a cluster of Server objects (i.e. socket connections). * * Typically, users will connect to a cluster using a URI, and the Manager will * perform tasks such as replica set discovery and create the necessary Server * objects. That said, it is also possible to create a Manager with an arbitrary * collection of Server objects using the static factory method (this can be * useful for testing or administration). * * Operation methods do not take socket-level options (e.g. socketTimeoutMS). * Those options should be specified during construction. */ /* {{{ MongoDB\Driver\Manager */ ZEND_BEGIN_ARG_INFO_EX(ai_Manager___construct, 0, 0, 0) ZEND_ARG_INFO(0, uri) ZEND_ARG_ARRAY_INFO(0, options, 0) ZEND_ARG_ARRAY_INFO(0, driverOptions, 0) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_Manager_executeCommand, 0, 0, 2) ZEND_ARG_INFO(0, db) ZEND_ARG_OBJ_INFO(0, command, MongoDB\\Driver\\Command, 0) ZEND_ARG_OBJ_INFO(0, readPreference, MongoDB\\Driver\\ReadPreference, 1) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_Manager_executeQuery, 0, 0, 2) ZEND_ARG_INFO(0, namespace) ZEND_ARG_OBJ_INFO(0, zquery, MongoDB\\Driver\\Query, 0) ZEND_ARG_OBJ_INFO(0, readPreference, MongoDB\\Driver\\ReadPreference, 1) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_Manager_executeBulkWrite, 0, 0, 2) ZEND_ARG_INFO(0, namespace) ZEND_ARG_OBJ_INFO(0, zbulk, MongoDB\\Driver\\BulkWrite, 0) ZEND_ARG_OBJ_INFO(0, writeConcern, MongoDB\\Driver\\WriteConcern, 1) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_Manager_getReadConcern, 0, 0, 0) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_Manager_getReadPreference, 0, 0, 0) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_Manager_getServers, 0, 0, 0) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_Manager_getWriteConcern, 0, 0, 0) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_Manager_selectServer, 0, 0, 1) ZEND_ARG_OBJ_INFO(0, readPreference, MongoDB\\Driver\\ReadPreference, 1) ZEND_END_ARG_INFO(); static zend_function_entry php_phongo_manager_me[] = { PHP_ME(Manager, __construct, ai_Manager___construct, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Manager, executeCommand, ai_Manager_executeCommand, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Manager, executeQuery, ai_Manager_executeQuery, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Manager, executeBulkWrite, ai_Manager_executeBulkWrite, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Manager, getReadConcern, ai_Manager_getReadConcern, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Manager, getReadPreference, ai_Manager_getReadPreference, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Manager, getServers, ai_Manager_getServers, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Manager, getWriteConcern, ai_Manager_getWriteConcern, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Manager, selectServer, ai_Manager_selectServer, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Manager, __wakeUp, NULL, ZEND_ACC_PUBLIC) PHP_FE_END }; /* }}} */ /* {{{ php_phongo_manager_t object handlers */ static void php_phongo_manager_free_object(phongo_free_object_arg *object TSRMLS_DC) /* {{{ */ { php_phongo_manager_t *intern = Z_OBJ_MANAGER(object); zend_object_std_dtor(&intern->std TSRMLS_CC); if (intern->client) { mongoc_client_destroy(intern->client); } #if PHP_VERSION_ID < 70000 efree(intern); #endif } /* }}} */ phongo_create_object_retval php_phongo_manager_create_object(zend_class_entry *class_type TSRMLS_DC) /* {{{ */ { php_phongo_manager_t *intern = NULL; intern = PHONGO_ALLOC_OBJECT_T(php_phongo_manager_t, class_type); zend_object_std_init(&intern->std, class_type TSRMLS_CC); object_properties_init(&intern->std, class_type); #if PHP_VERSION_ID >= 70000 intern->std.handlers = &php_phongo_handler_manager; return &intern->std; #else { zend_object_value retval; retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_manager_free_object, NULL TSRMLS_CC); retval.handlers = &php_phongo_handler_manager; return retval; } #endif } /* }}} */ bool phongo_add_server_debug(void *item, void *ctx) /* {{{ */ { mongoc_server_description_t *server = item; zval *retval = ctx; #if PHP_VERSION_ID >= 70000 zval entry; php_phongo_server_to_zval(&entry, server); add_next_index_zval(retval, &entry); #else zval *entry = NULL; MAKE_STD_ZVAL(entry); php_phongo_server_to_zval(entry, server); add_next_index_zval(retval, entry); #endif return true; } /* }}} */ HashTable *php_phongo_manager_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */ { php_phongo_manager_t *intern; #if PHP_VERSION_ID >= 70000 zval retval; #else zval retval = zval_used_for_init; #endif *is_temp = 1; intern = Z_MANAGER_OBJ_P(object); array_init(&retval); ADD_ASSOC_STRING(&retval, "uri", (char *)mongoc_uri_get_string(intern->client->uri)); { #if PHP_VERSION_ID >= 70000 zval cluster; array_init(&cluster); mongoc_set_for_each(intern->client->topology->description.servers, phongo_add_server_debug, &cluster); ADD_ASSOC_ZVAL_EX(&retval, "cluster", &cluster); #else zval *cluster = NULL; MAKE_STD_ZVAL(cluster); array_init(cluster); mongoc_set_for_each(intern->client->topology->description.servers, phongo_add_server_debug, cluster); ADD_ASSOC_ZVAL_EX(&retval, "cluster", cluster); #endif } return Z_ARRVAL(retval); } /* }}} */ /* }}} */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(Manager) { zend_class_entry ce; (void)type;(void)module_number; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver", "Manager", php_phongo_manager_me); php_phongo_manager_ce = zend_register_internal_class(&ce TSRMLS_CC); php_phongo_manager_ce->create_object = php_phongo_manager_create_object; PHONGO_CE_INIT(php_phongo_manager_ce); memcpy(&php_phongo_handler_manager, phongo_get_std_object_handlers(), sizeof(zend_object_handlers)); php_phongo_handler_manager.get_debug_info = php_phongo_manager_get_debug_info; #if PHP_VERSION_ID >= 70000 php_phongo_handler_manager.free_obj = php_phongo_manager_free_object; php_phongo_handler_manager.offset = XtOffsetOf(php_phongo_manager_t, std); #endif return SUCCESS; } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mongodb-1.1.5/src/MongoDB/Query.c0000664000175000017500000002105112673034026016332 0ustar jmikolajmikola/* +---------------------------------------------------------------------------+ | PHP Driver for MongoDB | +---------------------------------------------------------------------------+ | Copyright 2013-2015 MongoDB, Inc. | | | | Licensed under the Apache License, Version 2.0 (the "License"); | | you may not use this file except in compliance with the License. | | You may obtain a copy of the License at | | | | http://www.apache.org/licenses/LICENSE-2.0 | | | | Unless required by applicable law or agreed to in writing, software | | distributed under the License is distributed on an "AS IS" BASIS, | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | See the License for the specific language governing permissions and | | limitations under the License. | +---------------------------------------------------------------------------+ | Copyright (c) 2014-2015 MongoDB, Inc. | +---------------------------------------------------------------------------+ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif /* External libs */ #include #include /* PHP Core stuff */ #include #include #include #include #include /* PHP array helpers */ #include "php_array_api.h" /* Our Compatability header */ #include "phongo_compat.h" /* Our stuffz */ #include "php_phongo.h" #include "php_bson.h" PHONGO_API zend_class_entry *php_phongo_query_ce; zend_object_handlers php_phongo_handler_query; /* {{{ proto MongoDB\Driver\Query Query::__construct(array|object $filter[, array $options = array()]) Constructs a new Query */ PHP_METHOD(Query, __construct) { php_phongo_query_t *intern; zend_error_handling error_handling; zval *zfilter; zval *zoptions = NULL; bson_t bfilter; bson_t boptions = BSON_INITIALIZER; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value) SUPPRESS_UNUSED_WARNING(return_value_used) zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC); intern = Z_QUERY_OBJ_P(getThis()); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "A|a!", &zfilter, &zoptions) == FAILURE) { zend_restore_error_handling(&error_handling TSRMLS_CC); return; } zend_restore_error_handling(&error_handling TSRMLS_CC); intern->query = bson_new(); bson_init(&bfilter); phongo_zval_to_bson(zfilter, PHONGO_BSON_NONE, &bfilter, NULL TSRMLS_CC); if (zoptions) { if (php_array_exists(zoptions, "readConcern")) { zval *zread_concern = php_array_fetchc(zoptions, "readConcern"); if (Z_TYPE_P(zread_concern) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(zread_concern), php_phongo_readconcern_ce TSRMLS_CC)) { #if PHP_VERSION_ID >= 70000 phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"readConcern\" option to be %s, %s given", ZSTR_VAL(php_phongo_readconcern_ce->name), zend_get_type_by_const(Z_TYPE_P(zread_concern))); #else phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected \"readConcern\" option to be %s, %s given", php_phongo_readconcern_ce->name, zend_get_type_by_const(Z_TYPE_P(zread_concern))); #endif bson_clear(&intern->query); return; } intern->read_concern = mongoc_read_concern_copy(phongo_read_concern_from_zval(zread_concern TSRMLS_CC)); php_array_unsetc(zoptions, "readConcern"); } phongo_zval_to_bson(zoptions, PHONGO_BSON_NONE, &boptions, NULL TSRMLS_CC); } if (!phongo_query_init(intern, &bfilter, &boptions TSRMLS_CC)) { bson_clear(&intern->query); } bson_destroy(&bfilter); bson_destroy(&boptions); } /* }}} */ /* {{{ MongoDB\Driver\Query */ ZEND_BEGIN_ARG_INFO_EX(ai_Query___construct, 0, 0, 1) ZEND_ARG_INFO(0, filter) ZEND_ARG_ARRAY_INFO(0, options, 0) ZEND_END_ARG_INFO(); static zend_function_entry php_phongo_query_me[] = { PHP_ME(Query, __construct, ai_Query___construct, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Manager, __wakeUp, NULL, ZEND_ACC_PUBLIC) PHP_FE_END }; /* }}} */ /* {{{ php_phongo_query_t object handlers */ static void php_phongo_query_free_object(phongo_free_object_arg *object TSRMLS_DC) /* {{{ */ { php_phongo_query_t *intern = Z_OBJ_QUERY(object); zend_object_std_dtor(&intern->std TSRMLS_CC); if (intern->selector) { bson_clear(&intern->selector); } if (intern->query) { bson_clear(&intern->query); } if (intern->read_concern) { mongoc_read_concern_destroy(intern->read_concern); } #if PHP_VERSION_ID < 70000 efree(intern); #endif } /* }}} */ phongo_create_object_retval php_phongo_query_create_object(zend_class_entry *class_type TSRMLS_DC) /* {{{ */ { php_phongo_query_t *intern = NULL; intern = PHONGO_ALLOC_OBJECT_T(php_phongo_query_t, class_type); zend_object_std_init(&intern->std, class_type TSRMLS_CC); object_properties_init(&intern->std, class_type); #if PHP_VERSION_ID >= 70000 intern->std.handlers = &php_phongo_handler_query; return &intern->std; #else { zend_object_value retval; retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_query_free_object, NULL TSRMLS_CC); retval.handlers = &php_phongo_handler_query; return retval; } #endif } /* }}} */ HashTable *php_phongo_query_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */ { php_phongo_query_t *intern; #if PHP_VERSION_ID >= 70000 zval retval; #else zval retval = zval_used_for_init; #endif *is_temp = 1; intern = Z_QUERY_OBJ_P(object); array_init_size(&retval, 6); /* Avoid using PHONGO_TYPEMAP_NATIVE_ARRAY for decoding query and selector * documents so that users can differentiate BSON arrays and documents. */ if (intern->query) { #if PHP_VERSION_ID >= 70000 zval zv; #else zval *zv; #endif phongo_bson_to_zval(bson_get_data(intern->query), intern->query->len, &zv); #if PHP_VERSION_ID >= 70000 ADD_ASSOC_ZVAL_EX(&retval, "query", &zv); #else ADD_ASSOC_ZVAL_EX(&retval, "query", zv); #endif } else { ADD_ASSOC_NULL_EX(&retval, "query"); } if (intern->selector) { #if PHP_VERSION_ID >= 70000 zval zv; #else zval *zv; #endif phongo_bson_to_zval(bson_get_data(intern->selector), intern->selector->len, &zv); #if PHP_VERSION_ID >= 70000 ADD_ASSOC_ZVAL_EX(&retval, "selector", &zv); #else ADD_ASSOC_ZVAL_EX(&retval, "selector", zv); #endif } else { ADD_ASSOC_NULL_EX(&retval, "selector"); } ADD_ASSOC_LONG_EX(&retval, "flags", intern->flags); ADD_ASSOC_LONG_EX(&retval, "skip", intern->skip); ADD_ASSOC_LONG_EX(&retval, "limit", intern->limit); ADD_ASSOC_LONG_EX(&retval, "batch_size", intern->batch_size); if (intern->read_concern) { #if PHP_VERSION_ID >= 70000 zval read_concern; php_phongo_read_concern_to_zval(&read_concern, intern->read_concern); ADD_ASSOC_ZVAL_EX(&retval, "readConcern", &read_concern); #else zval *read_concern = NULL; MAKE_STD_ZVAL(read_concern); php_phongo_read_concern_to_zval(read_concern, intern->read_concern); ADD_ASSOC_ZVAL_EX(&retval, "readConcern", read_concern); #endif } else { ADD_ASSOC_NULL_EX(&retval, "readConcern"); } return Z_ARRVAL(retval); } /* }}} */ /* }}} */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(Query) { zend_class_entry ce; (void)type;(void)module_number; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver", "Query", php_phongo_query_me); php_phongo_query_ce = zend_register_internal_class(&ce TSRMLS_CC); php_phongo_query_ce->create_object = php_phongo_query_create_object; PHONGO_CE_INIT(php_phongo_query_ce); memcpy(&php_phongo_handler_query, phongo_get_std_object_handlers(), sizeof(zend_object_handlers)); php_phongo_handler_query.get_debug_info = php_phongo_query_get_debug_info; #if PHP_VERSION_ID >= 70000 php_phongo_handler_query.free_obj = php_phongo_query_free_object; php_phongo_handler_query.offset = XtOffsetOf(php_phongo_query_t, std); #endif return SUCCESS; } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mongodb-1.1.5/src/MongoDB/ReadConcern.c0000664000175000017500000001546212673034026017421 0ustar jmikolajmikola/* +---------------------------------------------------------------------------+ | PHP Driver for MongoDB | +---------------------------------------------------------------------------+ | Copyright 2013-2015 MongoDB, Inc. | | | | Licensed under the Apache License, Version 2.0 (the "License"); | | you may not use this file except in compliance with the License. | | You may obtain a copy of the License at | | | | http://www.apache.org/licenses/LICENSE-2.0 | | | | Unless required by applicable law or agreed to in writing, software | | distributed under the License is distributed on an "AS IS" BASIS, | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | See the License for the specific language governing permissions and | | limitations under the License. | +---------------------------------------------------------------------------+ | Copyright (c) 2014-2015 MongoDB, Inc. | +---------------------------------------------------------------------------+ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif /* External libs */ #include #include #include /* PHP Core stuff */ #include #include #include #include #include /* Our Compatability header */ #include "phongo_compat.h" /* Our stuffz */ #include "php_phongo.h" #include "php_bson.h" PHONGO_API zend_class_entry *php_phongo_readconcern_ce; zend_object_handlers php_phongo_handler_readconcern; /* {{{ proto MongoDB\Driver\ReadConcern ReadConcern::__construct([string $level]) Constructs a new ReadConcern */ PHP_METHOD(ReadConcern, __construct) { php_phongo_readconcern_t *intern; zend_error_handling error_handling; char *level = NULL; phongo_zpp_char_len level_len = 0; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value) SUPPRESS_UNUSED_WARNING(return_value_used) zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC); intern = Z_READCONCERN_OBJ_P(getThis()); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!", &level, &level_len) == FAILURE) { zend_restore_error_handling(&error_handling TSRMLS_CC); return; } zend_restore_error_handling(&error_handling TSRMLS_CC); intern->read_concern = mongoc_read_concern_new(); if (level) { mongoc_read_concern_set_level(intern->read_concern, level); } } /* }}} */ /* {{{ proto string|null ReadConcern::getLevel() Returns the ReadConcern "level" option */ PHP_METHOD(ReadConcern, getLevel) { php_phongo_readconcern_t *intern; const char *level; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_READCONCERN_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } level = mongoc_read_concern_get_level(intern->read_concern); if (level) { PHONGO_RETURN_STRING(level); } RETURN_NULL(); } /* }}} */ /** * Value object for read concern used in issuing read operations. */ /* {{{ MongoDB\Driver\ReadConcern */ ZEND_BEGIN_ARG_INFO_EX(ai_ReadConcern___construct, 0, 0, 0) ZEND_ARG_INFO(0, level) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_ReadConcern_getLevel, 0, 0, 0) ZEND_END_ARG_INFO(); static zend_function_entry php_phongo_readconcern_me[] = { PHP_ME(ReadConcern, __construct, ai_ReadConcern___construct, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(ReadConcern, getLevel, ai_ReadConcern_getLevel, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_FE_END }; /* }}} */ /* {{{ php_phongo_readconcern_t object handlers */ static void php_phongo_readconcern_free_object(phongo_free_object_arg *object TSRMLS_DC) /* {{{ */ { php_phongo_readconcern_t *intern = Z_OBJ_READCONCERN(object); zend_object_std_dtor(&intern->std TSRMLS_CC); if (intern->read_concern) { mongoc_read_concern_destroy(intern->read_concern); } #if PHP_VERSION_ID < 70000 efree(intern); #endif } /* }}} */ phongo_create_object_retval php_phongo_readconcern_create_object(zend_class_entry *class_type TSRMLS_DC) /* {{{ */ { php_phongo_readconcern_t *intern = NULL; intern = PHONGO_ALLOC_OBJECT_T(php_phongo_readconcern_t, class_type); zend_object_std_init(&intern->std, class_type TSRMLS_CC); object_properties_init(&intern->std, class_type); #if PHP_VERSION_ID >= 70000 intern->std.handlers = &php_phongo_handler_readconcern; return &intern->std; #else { zend_object_value retval; retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_readconcern_free_object, NULL TSRMLS_CC); retval.handlers = &php_phongo_handler_readconcern; return retval; } #endif } /* }}} */ HashTable *php_phongo_readconcern_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */ { #if PHP_VERSION_ID >= 70000 zval retval; #else zval retval = zval_used_for_init; #endif const mongoc_read_concern_t *read_concern = phongo_read_concern_from_zval(object TSRMLS_CC); *is_temp = 1; php_phongo_read_concern_to_zval(&retval, read_concern); return Z_ARRVAL(retval); } /* }}} */ /* }}} */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(ReadConcern) { zend_class_entry ce; (void)type;(void)module_number; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver", "ReadConcern", php_phongo_readconcern_me); php_phongo_readconcern_ce = zend_register_internal_class(&ce TSRMLS_CC); php_phongo_readconcern_ce->create_object = php_phongo_readconcern_create_object; PHONGO_CE_INIT(php_phongo_readconcern_ce); memcpy(&php_phongo_handler_readconcern, phongo_get_std_object_handlers(), sizeof(zend_object_handlers)); php_phongo_handler_readconcern.get_debug_info = php_phongo_readconcern_get_debug_info; #if PHP_VERSION_ID >= 70000 php_phongo_handler_readconcern.free_obj = php_phongo_readconcern_free_object; php_phongo_handler_readconcern.offset = XtOffsetOf(php_phongo_readconcern_t, std); #endif zend_declare_class_constant_stringl(php_phongo_readconcern_ce, ZEND_STRL("LOCAL"), ZEND_STRL(MONGOC_READ_CONCERN_LEVEL_LOCAL) TSRMLS_CC); zend_declare_class_constant_stringl(php_phongo_readconcern_ce, ZEND_STRL("MAJORITY"), ZEND_STRL(MONGOC_READ_CONCERN_LEVEL_MAJORITY) TSRMLS_CC); return SUCCESS; } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mongodb-1.1.5/src/MongoDB/ReadPreference.c0000664000175000017500000002175112673034026020106 0ustar jmikolajmikola/* +---------------------------------------------------------------------------+ | PHP Driver for MongoDB | +---------------------------------------------------------------------------+ | Copyright 2013-2015 MongoDB, Inc. | | | | Licensed under the Apache License, Version 2.0 (the "License"); | | you may not use this file except in compliance with the License. | | You may obtain a copy of the License at | | | | http://www.apache.org/licenses/LICENSE-2.0 | | | | Unless required by applicable law or agreed to in writing, software | | distributed under the License is distributed on an "AS IS" BASIS, | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | See the License for the specific language governing permissions and | | limitations under the License. | +---------------------------------------------------------------------------+ | Copyright (c) 2014-2015 MongoDB, Inc. | +---------------------------------------------------------------------------+ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif /* External libs */ #include #include #include /* PHP Core stuff */ #include #include #include #include #include /* Our Compatability header */ #include "phongo_compat.h" /* Our stuffz */ #include "php_phongo.h" #include "php_bson.h" PHONGO_API zend_class_entry *php_phongo_readpreference_ce; zend_object_handlers php_phongo_handler_readpreference; /* {{{ proto MongoDB\Driver\ReadPreference ReadPreference::__construct(integer $mode[, array $tagSets = array()]) Constructs a new ReadPreference */ PHP_METHOD(ReadPreference, __construct) { php_phongo_readpreference_t *intern; zend_error_handling error_handling; long mode; zval *tagSets = NULL; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value) SUPPRESS_UNUSED_WARNING(return_value_used) zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC); intern = Z_READPREFERENCE_OBJ_P(getThis()); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|a!", &mode, &tagSets) == FAILURE) { zend_restore_error_handling(&error_handling TSRMLS_CC); return; } zend_restore_error_handling(&error_handling TSRMLS_CC); switch(mode) { case MONGOC_READ_PRIMARY: case MONGOC_READ_SECONDARY: case MONGOC_READ_PRIMARY_PREFERRED: case MONGOC_READ_SECONDARY_PREFERRED: case MONGOC_READ_NEAREST: intern->read_preference = mongoc_read_prefs_new(mode); if (tagSets) { bson_t *tags = bson_new(); phongo_zval_to_bson(tagSets, PHONGO_BSON_NONE, (bson_t *)tags, NULL TSRMLS_CC); mongoc_read_prefs_set_tags(intern->read_preference, tags); bson_destroy(tags); if (!mongoc_read_prefs_is_valid(intern->read_preference)) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Invalid tagSets"); return; } } break; default: phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Invalid mode: %ld", mode); return; } } /* }}} */ /* {{{ proto integer ReadPreference::getMode() Returns the ReadPreference mode */ PHP_METHOD(ReadPreference, getMode) { php_phongo_readpreference_t *intern; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_READPREFERENCE_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } RETURN_LONG(mongoc_read_prefs_get_mode(intern->read_preference)); } /* }}} */ /* {{{ proto array ReadPreference::getTagSets() Returns the ReadPreference tag sets */ PHP_METHOD(ReadPreference, getTagSets) { php_phongo_readpreference_t *intern; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_READPREFERENCE_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } if (intern->read_preference->tags.len) { php_phongo_bson_state state = PHONGO_BSON_STATE_INITIALIZER; /* Use native arrays for debugging output */ state.map.root_type = PHONGO_TYPEMAP_NATIVE_ARRAY; state.map.document_type = PHONGO_TYPEMAP_NATIVE_ARRAY; phongo_bson_to_zval_ex(bson_get_data(&intern->read_preference->tags), intern->read_preference->tags.len, &state); #if PHP_VERSION_ID >= 70000 RETURN_ZVAL(&state.zchild, 0, 1); #else RETURN_ZVAL(state.zchild, 0, 1); #endif } else { RETURN_NULL(); } } /* }}} */ /** * Value object for read preferences used in issuing commands and queries. */ /* {{{ MongoDB\Driver\ReadPreference */ ZEND_BEGIN_ARG_INFO_EX(ai_ReadPreference___construct, 0, 0, 1) ZEND_ARG_INFO(0, mode) ZEND_ARG_ARRAY_INFO(0, tagSets, 1) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_ReadPreference_getMode, 0, 0, 0) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_ReadPreference_getTagSets, 0, 0, 0) ZEND_END_ARG_INFO(); static zend_function_entry php_phongo_readpreference_me[] = { PHP_ME(ReadPreference, __construct, ai_ReadPreference___construct, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(ReadPreference, getMode, ai_ReadPreference_getMode, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(ReadPreference, getTagSets, ai_ReadPreference_getTagSets, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_FE_END }; /* }}} */ /* {{{ php_phongo_readpreference_t object handlers */ static void php_phongo_readpreference_free_object(phongo_free_object_arg *object TSRMLS_DC) /* {{{ */ { php_phongo_readpreference_t *intern = Z_OBJ_READPREFERENCE(object); zend_object_std_dtor(&intern->std TSRMLS_CC); if (intern->read_preference) { mongoc_read_prefs_destroy(intern->read_preference); } #if PHP_VERSION_ID < 70000 efree(intern); #endif } /* }}} */ phongo_create_object_retval php_phongo_readpreference_create_object(zend_class_entry *class_type TSRMLS_DC) /* {{{ */ { php_phongo_readpreference_t *intern = NULL; intern = PHONGO_ALLOC_OBJECT_T(php_phongo_readpreference_t, class_type); zend_object_std_init(&intern->std, class_type TSRMLS_CC); object_properties_init(&intern->std, class_type); #if PHP_VERSION_ID >= 70000 intern->std.handlers = &php_phongo_handler_readpreference; return &intern->std; #else { zend_object_value retval; retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_readpreference_free_object, NULL TSRMLS_CC); retval.handlers = &php_phongo_handler_readpreference; return retval; } #endif } /* }}} */ HashTable *php_phongo_readpreference_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */ { #if PHP_VERSION_ID >= 70000 zval retval; #else zval retval = zval_used_for_init; #endif const mongoc_read_prefs_t *read_prefs = phongo_read_preference_from_zval(object TSRMLS_CC); *is_temp = 1; php_phongo_read_preference_to_zval(&retval, read_prefs); return Z_ARRVAL(retval); } /* }}} */ /* }}} */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(ReadPreference) { zend_class_entry ce; (void)type;(void)module_number; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver", "ReadPreference", php_phongo_readpreference_me); php_phongo_readpreference_ce = zend_register_internal_class(&ce TSRMLS_CC); php_phongo_readpreference_ce->create_object = php_phongo_readpreference_create_object; PHONGO_CE_INIT(php_phongo_readpreference_ce); memcpy(&php_phongo_handler_readpreference, phongo_get_std_object_handlers(), sizeof(zend_object_handlers)); php_phongo_handler_readpreference.get_debug_info = php_phongo_readpreference_get_debug_info; #if PHP_VERSION_ID >= 70000 php_phongo_handler_readpreference.free_obj = php_phongo_readpreference_free_object; php_phongo_handler_readpreference.offset = XtOffsetOf(php_phongo_readpreference_t, std); #endif zend_declare_class_constant_long(php_phongo_readpreference_ce, ZEND_STRL("RP_PRIMARY"), MONGOC_READ_PRIMARY TSRMLS_CC); zend_declare_class_constant_long(php_phongo_readpreference_ce, ZEND_STRL("RP_PRIMARY_PREFERRED"), MONGOC_READ_PRIMARY_PREFERRED TSRMLS_CC); zend_declare_class_constant_long(php_phongo_readpreference_ce, ZEND_STRL("RP_SECONDARY"), MONGOC_READ_SECONDARY TSRMLS_CC); zend_declare_class_constant_long(php_phongo_readpreference_ce, ZEND_STRL("RP_SECONDARY_PREFERRED"), MONGOC_READ_SECONDARY_PREFERRED TSRMLS_CC); zend_declare_class_constant_long(php_phongo_readpreference_ce, ZEND_STRL("RP_NEAREST"), MONGOC_READ_NEAREST TSRMLS_CC); return SUCCESS; } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mongodb-1.1.5/src/MongoDB/Server.c0000664000175000017500000005304212673034026016500 0ustar jmikolajmikola/* +---------------------------------------------------------------------------+ | PHP Driver for MongoDB | +---------------------------------------------------------------------------+ | Copyright 2013-2015 MongoDB, Inc. | | | | Licensed under the Apache License, Version 2.0 (the "License"); | | you may not use this file except in compliance with the License. | | You may obtain a copy of the License at | | | | http://www.apache.org/licenses/LICENSE-2.0 | | | | Unless required by applicable law or agreed to in writing, software | | distributed under the License is distributed on an "AS IS" BASIS, | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | See the License for the specific language governing permissions and | | limitations under the License. | +---------------------------------------------------------------------------+ | Copyright (c) 2014-2015 MongoDB, Inc. | +---------------------------------------------------------------------------+ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif /* External libs */ #include #include #include /* PHP Core stuff */ #include #include #include #include #include #include /* Our Compatability header */ #include "phongo_compat.h" /* Our stuffz */ #include "php_phongo.h" #include "php_bson.h" PHONGO_API zend_class_entry *php_phongo_server_ce; zend_object_handlers php_phongo_handler_server; /* {{{ proto MongoDB\Driver\Server Server::__construct() Throws exception -- can only be created internally */ PHP_METHOD(Server, __construct) { SUPPRESS_UNUSED_WARNING(return_value) SUPPRESS_UNUSED_WARNING(return_value_used) SUPPRESS_UNUSED_WARNING(return_value_ptr) (void)ZEND_NUM_ARGS(); (void)getThis(); phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Accessing private constructor"); } /* }}} */ /* {{{ proto MongoDB\Driver\Cursor Server::executeCommand(string $db, MongoDB\Driver\Command $command[, MongoDB\Driver\ReadPreference $readPreference = null])) Executes a command on this server */ PHP_METHOD(Server, executeCommand) { php_phongo_server_t *intern; char *db; phongo_zpp_char_len db_len; zval *command; zval *readPreference = NULL; php_phongo_command_t *cmd; DECLARE_RETURN_VALUE_USED SUPPRESS_UNUSED_WARNING(return_value_ptr) intern = Z_SERVER_OBJ_P(getThis()); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sO|O!", &db, &db_len, &command, php_phongo_command_ce, &readPreference, php_phongo_readpreference_ce) == FAILURE) { return; } cmd = Z_COMMAND_OBJ_P(command); phongo_execute_command(intern->client, db, cmd->bson, phongo_read_preference_from_zval(readPreference TSRMLS_CC), intern->server_id, return_value, return_value_used TSRMLS_CC); } /* }}} */ /* {{{ proto MongoDB\Driver\Cursor Server::executeQuery(string $namespace, MongoDB\Driver\Query $zquery[, MongoDB\Driver\ReadPreference $readPreference = null])) Executes a Query */ PHP_METHOD(Server, executeQuery) { php_phongo_server_t *intern; char *namespace; phongo_zpp_char_len namespace_len; zval *zquery; zval *readPreference = NULL; DECLARE_RETURN_VALUE_USED SUPPRESS_UNUSED_WARNING(return_value_ptr) intern = Z_SERVER_OBJ_P(getThis()); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sO|O!", &namespace, &namespace_len, &zquery, php_phongo_query_ce, &readPreference, php_phongo_readpreference_ce) == FAILURE) { return; } phongo_execute_query(intern->client, namespace, phongo_query_from_zval(zquery TSRMLS_CC), phongo_read_preference_from_zval(readPreference TSRMLS_CC), intern->server_id, return_value, return_value_used TSRMLS_CC); } /* }}} */ /* {{{ proto MongoDB\Driver\WriteResult Server::executeBulkWrite(string $namespace, MongoDB\Driver\BulkWrite $zbulk[, MongoDB\Driver\WriteConcern $writeConcern = null]) Executes a write operation bulk (e.g. insert, update, delete) */ PHP_METHOD(Server, executeBulkWrite) { php_phongo_server_t *intern; char *namespace; phongo_zpp_char_len namespace_len; zval *zbulk; zval *zwrite_concern = NULL; php_phongo_bulkwrite_t *bulk; DECLARE_RETURN_VALUE_USED SUPPRESS_UNUSED_WARNING(return_value_ptr) intern = Z_SERVER_OBJ_P(getThis()); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sO|O!", &namespace, &namespace_len, &zbulk, php_phongo_bulkwrite_ce, &zwrite_concern, php_phongo_writeconcern_ce) == FAILURE) { return; } bulk = Z_BULKWRITE_OBJ_P(zbulk); phongo_execute_write(intern->client, namespace, bulk->bulk, phongo_write_concern_from_zval(zwrite_concern TSRMLS_CC), intern->server_id, return_value, return_value_used TSRMLS_CC); } /* }}} */ /* {{{ proto string Server::getHost() Returns the hostname used to connect to this Server */ PHP_METHOD(Server, getHost) { php_phongo_server_t *intern; mongoc_server_description_t *sd; bson_error_t error; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_SERVER_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } if ((sd = mongoc_topology_description_server_by_id(&intern->client->topology->description, intern->server_id, &error))) { PHONGO_RETURN_STRING(sd->host.host); } phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description: %s", error.message); } /* }}} */ /* {{{ proto array Server::getTags() Returns the currently configured tags for this node */ PHP_METHOD(Server, getTags) { php_phongo_server_t *intern; mongoc_server_description_t *sd; bson_error_t error; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_SERVER_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } if ((sd = mongoc_topology_description_server_by_id(&intern->client->topology->description, intern->server_id, &error))) { php_phongo_bson_state state = PHONGO_BSON_STATE_INITIALIZER; state.map.root_type = PHONGO_TYPEMAP_NATIVE_ARRAY; state.map.document_type = PHONGO_TYPEMAP_NATIVE_ARRAY; phongo_bson_to_zval_ex(bson_get_data(&sd->tags), sd->tags.len, &state); #if PHP_VERSION_ID >= 70000 RETURN_ZVAL(&state.zchild, 0, 1); #else RETURN_ZVAL(state.zchild, 0, 1); #endif } phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description: %s", error.message); } /* }}} */ /* {{{ proto array Server::getInfo() Returns the last isMaster() result document */ PHP_METHOD(Server, getInfo) { php_phongo_server_t *intern; mongoc_server_description_t *sd; bson_error_t error; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_SERVER_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } if ((sd = mongoc_topology_description_server_by_id(&intern->client->topology->description, intern->server_id, &error))) { php_phongo_bson_state state = PHONGO_BSON_STATE_INITIALIZER; state.map.root_type = PHONGO_TYPEMAP_NATIVE_ARRAY; state.map.document_type = PHONGO_TYPEMAP_NATIVE_ARRAY; phongo_bson_to_zval_ex(bson_get_data(&sd->last_is_master), sd->last_is_master.len, &state); #if PHP_VERSION_ID >= 70000 RETURN_ZVAL(&state.zchild, 0, 1); #else RETURN_ZVAL(state.zchild, 0, 1); #endif } phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description: %s", error.message); } /* }}} */ /* {{{ proto integer Server::getLatency() Returns the last messured latency */ PHP_METHOD(Server, getLatency) { php_phongo_server_t *intern; mongoc_server_description_t *sd; bson_error_t error; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_SERVER_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } if ((sd = mongoc_topology_description_server_by_id(&intern->client->topology->description, intern->server_id, &error))) { RETURN_LONG(sd->round_trip_time); } phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description: %s", error.message); } /* }}} */ /* {{{ proto integer Server::getPort() Returns the port used to create this Server */ PHP_METHOD(Server, getPort) { php_phongo_server_t *intern; mongoc_server_description_t *sd; bson_error_t error; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_SERVER_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } if ((sd = mongoc_topology_description_server_by_id(&intern->client->topology->description, intern->server_id, &error))) { RETURN_LONG(sd->host.port); } phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description: %s", error.message); } /* }}} */ /* {{{ proto integer Server::getType() Returns the node type of this Server */ PHP_METHOD(Server, getType) { php_phongo_server_t *intern; mongoc_server_description_t *sd; bson_error_t error; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_SERVER_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } if ((sd = mongoc_topology_description_server_by_id(&intern->client->topology->description, intern->server_id, &error))) { RETURN_LONG(sd->type); } phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description: %s", error.message); } /* }}} */ /* {{{ proto bool Server::isPrimary() Checks if this is a special "Primary" member of a RepilcaSet */ PHP_METHOD(Server, isPrimary) { php_phongo_server_t *intern; mongoc_server_description_t *sd; bson_error_t error; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_SERVER_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } if ((sd = mongoc_topology_description_server_by_id(&intern->client->topology->description, intern->server_id, &error))) { RETURN_BOOL(sd->type == MONGOC_SERVER_RS_PRIMARY); } phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description: %s", error.message); } /* }}} */ /* {{{ proto bool Server::isSecondary() Checks if this is a special "Secondary" member of a RepilcaSet */ PHP_METHOD(Server, isSecondary) { php_phongo_server_t *intern; mongoc_server_description_t *sd; bson_error_t error; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_SERVER_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } if ((sd = mongoc_topology_description_server_by_id(&intern->client->topology->description, intern->server_id, &error))) { RETURN_BOOL(sd->type == MONGOC_SERVER_RS_SECONDARY); } phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description: %s", error.message); } /* }}} */ /* {{{ proto bool Server::isArbiter() Checks if this is a special "Arbiter" member of a RepilcaSet */ PHP_METHOD(Server, isArbiter) { php_phongo_server_t *intern; mongoc_server_description_t *sd; bson_error_t error; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_SERVER_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } if ((sd = mongoc_topology_description_server_by_id(&intern->client->topology->description, intern->server_id, &error))) { RETURN_BOOL(sd->type == MONGOC_SERVER_RS_ARBITER); } phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description: %s", error.message); } /* }}} */ /* {{{ proto bool Server::isHidden() Checks if this is a special "hidden" member of a RepilcaSet */ PHP_METHOD(Server, isHidden) { php_phongo_server_t *intern; mongoc_server_description_t *sd; bson_error_t error; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_SERVER_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } if ((sd = mongoc_topology_description_server_by_id(&intern->client->topology->description, intern->server_id, &error))) { bson_iter_t iter; RETURN_BOOL(bson_iter_init_find_case(&iter, &sd->last_is_master, "hidden") && bson_iter_as_bool(&iter)); } phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description: %s", error.message); } /* }}} */ /* {{{ proto bool Server::isPassive() Checks if this is a special passive node member of a ReplicaSet */ PHP_METHOD(Server, isPassive) { php_phongo_server_t *intern; mongoc_server_description_t *sd; bson_error_t error; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_SERVER_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } if ((sd = mongoc_topology_description_server_by_id(&intern->client->topology->description, intern->server_id, &error))) { bson_iter_t iter; RETURN_BOOL(bson_iter_init_find_case(&iter, &sd->last_is_master, "passive") && bson_iter_as_bool(&iter)); } phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description: %s", error.message); } /* }}} */ /* {{{ MongoDB\Driver\Server */ ZEND_BEGIN_ARG_INFO_EX(ai_Server_executeCommand, 0, 0, 2) ZEND_ARG_INFO(0, db) ZEND_ARG_OBJ_INFO(0, command, MongoDB\\Driver\\Command, 0) ZEND_ARG_OBJ_INFO(0, readPreference, MongoDB\\Driver\\ReadPreference, 1) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_Server_executeQuery, 0, 0, 2) ZEND_ARG_INFO(0, namespace) ZEND_ARG_OBJ_INFO(0, zquery, MongoDB\\Driver\\Query, 0) ZEND_ARG_OBJ_INFO(0, readPreference, MongoDB\\Driver\\ReadPreference, 1) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_Server_executeBulkWrite, 0, 0, 2) ZEND_ARG_INFO(0, namespace) ZEND_ARG_OBJ_INFO(0, zbulk, MongoDB\\Driver\\BulkWrite, 0) ZEND_ARG_OBJ_INFO(0, writeConcern, MongoDB\\Driver\\WriteConcern, 1) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_Server_getHost, 0, 0, 0) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_Server_getTags, 0, 0, 0) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_Server_getInfo, 0, 0, 0) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_Server_getLatency, 0, 0, 0) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_Server_getPort, 0, 0, 0) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_Server_getType, 0, 0, 0) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_Server_isPrimary, 0, 0, 0) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_Server_isSecondary, 0, 0, 0) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_Server_isArbiter, 0, 0, 0) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_Server_isHidden, 0, 0, 0) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_Server_isPassive, 0, 0, 0) ZEND_END_ARG_INFO(); static zend_function_entry php_phongo_server_me[] = { PHP_ME(Server, __construct, NULL, ZEND_ACC_FINAL|ZEND_ACC_PRIVATE) PHP_ME(Server, executeCommand, ai_Server_executeCommand, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Server, executeQuery, ai_Server_executeQuery, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Server, executeBulkWrite, ai_Server_executeBulkWrite, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Server, getHost, ai_Server_getHost, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Server, getTags, ai_Server_getTags, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Server, getInfo, ai_Server_getInfo, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Server, getLatency, ai_Server_getLatency, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Server, getPort, ai_Server_getPort, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Server, getType, ai_Server_getType, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Server, isPrimary, ai_Server_isPrimary, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Server, isSecondary, ai_Server_isSecondary, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Server, isArbiter, ai_Server_isArbiter, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Server, isHidden, ai_Server_isHidden, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Server, isPassive, ai_Server_isPassive, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Manager, __wakeUp, NULL, ZEND_ACC_PUBLIC) PHP_FE_END }; /* }}} */ /* {{{ Other functions */ static int php_phongo_server_compare_objects(zval *o1, zval *o2 TSRMLS_DC) /* {{{ */ { php_phongo_server_t *intern1; php_phongo_server_t *intern2; bson_error_t error1; bson_error_t error2; mongoc_server_description_t *sd1, *sd2; intern1 = Z_SERVER_OBJ_P(o1); intern2 = Z_SERVER_OBJ_P(o2); sd1 = mongoc_topology_description_server_by_id(&intern1->client->topology->description, intern1->server_id, &error1); sd2 = mongoc_topology_description_server_by_id(&intern2->client->topology->description, intern2->server_id, &error2); if (!sd1 || !sd2) { if (!sd1 && !sd2) { phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server descriptions: %s and %s", error1.message, error2.message); } else if (!sd1) { phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description: %s", error1.message); } else { phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description: %s", error2.message); } return 0; } return strcasecmp(sd1->host.host_and_port, sd2->host.host_and_port); } /* }}} */ /* }}} */ /* {{{ php_phongo_server_t object handlers */ static void php_phongo_server_free_object(phongo_free_object_arg *object TSRMLS_DC) /* {{{ */ { php_phongo_server_t *intern = Z_OBJ_SERVER(object); zend_object_std_dtor(&intern->std TSRMLS_CC); #if PHP_VERSION_ID < 70000 efree(intern); #endif } /* }}} */ phongo_create_object_retval php_phongo_server_create_object(zend_class_entry *class_type TSRMLS_DC) /* {{{ */ { php_phongo_server_t *intern = NULL; intern = PHONGO_ALLOC_OBJECT_T(php_phongo_server_t, class_type); zend_object_std_init(&intern->std, class_type TSRMLS_CC); object_properties_init(&intern->std, class_type); #if PHP_VERSION_ID >= 70000 intern->std.handlers = &php_phongo_handler_server; return &intern->std; #else { zend_object_value retval; retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_server_free_object, NULL TSRMLS_CC); retval.handlers = &php_phongo_handler_server; return retval; } #endif } /* }}} */ HashTable *php_phongo_server_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */ { php_phongo_server_t *intern = NULL; #if PHP_VERSION_ID >= 70000 zval retval; #else zval retval = zval_used_for_init; #endif mongoc_server_description_t *sd; bson_error_t error; *is_temp = 1; intern = Z_SERVER_OBJ_P(object); if (!(sd = mongoc_topology_description_server_by_id(&intern->client->topology->description, intern->server_id, &error))) { phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to get server description: %s", error.message); return NULL; } php_phongo_server_to_zval(&retval, sd); return Z_ARRVAL(retval); } /* }}} */ /* }}} */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(Server) { zend_class_entry ce; (void)type;(void)module_number; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver", "Server", php_phongo_server_me); php_phongo_server_ce = zend_register_internal_class(&ce TSRMLS_CC); php_phongo_server_ce->create_object = php_phongo_server_create_object; PHONGO_CE_INIT(php_phongo_server_ce); memcpy(&php_phongo_handler_server, phongo_get_std_object_handlers(), sizeof(zend_object_handlers)); php_phongo_handler_server.compare_objects = php_phongo_server_compare_objects; php_phongo_handler_server.get_debug_info = php_phongo_server_get_debug_info; #if PHP_VERSION_ID >= 70000 php_phongo_handler_server.free_obj = php_phongo_server_free_object; php_phongo_handler_server.offset = XtOffsetOf(php_phongo_server_t, std); #endif zend_declare_class_constant_long(php_phongo_server_ce, ZEND_STRL("TYPE_UNKNOWN"), MONGOC_SERVER_UNKNOWN TSRMLS_CC); zend_declare_class_constant_long(php_phongo_server_ce, ZEND_STRL("TYPE_STANDALONE"), MONGOC_SERVER_STANDALONE TSRMLS_CC); zend_declare_class_constant_long(php_phongo_server_ce, ZEND_STRL("TYPE_MONGOS"), MONGOC_SERVER_MONGOS TSRMLS_CC); zend_declare_class_constant_long(php_phongo_server_ce, ZEND_STRL("TYPE_POSSIBLE_PRIMARY"), MONGOC_SERVER_POSSIBLE_PRIMARY TSRMLS_CC); zend_declare_class_constant_long(php_phongo_server_ce, ZEND_STRL("TYPE_RS_PRIMARY"), MONGOC_SERVER_RS_PRIMARY TSRMLS_CC); zend_declare_class_constant_long(php_phongo_server_ce, ZEND_STRL("TYPE_RS_SECONDARY"), MONGOC_SERVER_RS_SECONDARY TSRMLS_CC); zend_declare_class_constant_long(php_phongo_server_ce, ZEND_STRL("TYPE_RS_ARBITER"), MONGOC_SERVER_RS_ARBITER TSRMLS_CC); zend_declare_class_constant_long(php_phongo_server_ce, ZEND_STRL("TYPE_RS_OTHER"), MONGOC_SERVER_RS_OTHER TSRMLS_CC); zend_declare_class_constant_long(php_phongo_server_ce, ZEND_STRL("TYPE_RS_GHOST"), MONGOC_SERVER_RS_GHOST TSRMLS_CC); return SUCCESS; } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mongodb-1.1.5/src/MongoDB/WriteConcern.c0000664000175000017500000002347612673034026017644 0ustar jmikolajmikola/* +---------------------------------------------------------------------------+ | PHP Driver for MongoDB | +---------------------------------------------------------------------------+ | Copyright 2013-2015 MongoDB, Inc. | | | | Licensed under the Apache License, Version 2.0 (the "License"); | | you may not use this file except in compliance with the License. | | You may obtain a copy of the License at | | | | http://www.apache.org/licenses/LICENSE-2.0 | | | | Unless required by applicable law or agreed to in writing, software | | distributed under the License is distributed on an "AS IS" BASIS, | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | See the License for the specific language governing permissions and | | limitations under the License. | +---------------------------------------------------------------------------+ | Copyright (c) 2014-2015 MongoDB, Inc. | +---------------------------------------------------------------------------+ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif /* External libs */ #include #include #include /* PHP Core stuff */ #include #include #include #include #include /* Our Compatability header */ #include "phongo_compat.h" /* Our stuffz */ #include "php_phongo.h" #include "php_bson.h" PHONGO_API zend_class_entry *php_phongo_writeconcern_ce; zend_object_handlers php_phongo_handler_writeconcern; /* {{{ proto MongoDB\Driver\WriteConcern WriteConcern::__construct(integer|string $w[, integer $wtimeout[, boolean $journal]]) Constructs a new WriteConcern */ PHP_METHOD(WriteConcern, __construct) { php_phongo_writeconcern_t *intern; zend_error_handling error_handling; zval *w, *journal; phongo_long wtimeout = 0; SUPPRESS_UNUSED_WARNING(return_value) SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) zend_replace_error_handling(EH_THROW, phongo_exception_from_phongo_domain(PHONGO_ERROR_INVALID_ARGUMENT), &error_handling TSRMLS_CC); intern = Z_WRITECONCERN_OBJ_P(getThis()); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|lz", &w, &wtimeout, &journal) == FAILURE) { zend_restore_error_handling(&error_handling TSRMLS_CC); return; } zend_restore_error_handling(&error_handling TSRMLS_CC); intern->write_concern = mongoc_write_concern_new(); if (Z_TYPE_P(w) == IS_LONG) { if (Z_LVAL_P(w) < -3) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected w to be >= -3, %ld given", Z_LVAL_P(w)); return; } mongoc_write_concern_set_w(intern->write_concern, Z_LVAL_P(w)); } else if (Z_TYPE_P(w) == IS_STRING) { if (strcmp(Z_STRVAL_P(w), PHONGO_WRITE_CONCERN_W_MAJORITY) == 0) { mongoc_write_concern_set_w(intern->write_concern, MONGOC_WRITE_CONCERN_W_MAJORITY); } else { mongoc_write_concern_set_wtag(intern->write_concern, Z_STRVAL_P(w)); } } else { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected w to be integer or string, %s given", zend_get_type_by_const(Z_TYPE_P(w))); return; } switch(ZEND_NUM_ARGS()) { case 3: if (Z_TYPE_P(journal) != IS_NULL) { #ifdef ZEND_ENGINE_3 mongoc_write_concern_set_journal(intern->write_concern, zend_is_true(journal)); #else mongoc_write_concern_set_journal(intern->write_concern, Z_BVAL_P(journal)); #endif } /* fallthrough */ case 2: if (wtimeout < 0) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected wtimeout to be >= 0, %" PHONGO_LONG_FORMAT " given", wtimeout); return; } if (wtimeout > INT32_MAX) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected wtimeout to be <= %" PRId32 ", %" PHONGO_LONG_FORMAT " given", INT32_MAX, wtimeout); return; } mongoc_write_concern_set_wtimeout(intern->write_concern, wtimeout); } } /* }}} */ /* {{{ proto string|integer|null WriteConcern::getW() Returns the WriteConcern "w" option */ PHP_METHOD(WriteConcern, getW) { php_phongo_writeconcern_t *intern; const char *wtag; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_WRITECONCERN_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } wtag = mongoc_write_concern_get_wtag(intern->write_concern); if (wtag) { PHONGO_RETURN_STRING(wtag); } if (mongoc_write_concern_get_wmajority(intern->write_concern)) { PHONGO_RETURN_STRING(PHONGO_WRITE_CONCERN_W_MAJORITY); } if (intern->write_concern->w != MONGOC_WRITE_CONCERN_W_DEFAULT) { RETURN_LONG(mongoc_write_concern_get_w(intern->write_concern)); } RETURN_NULL(); } /* }}} */ /* {{{ proto integer WriteConcern::getWtimeout() Returns the WriteConcern "wtimeout" option */ PHP_METHOD(WriteConcern, getWtimeout) { php_phongo_writeconcern_t *intern; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_WRITECONCERN_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } RETURN_LONG(mongoc_write_concern_get_wtimeout(intern->write_concern)); } /* }}} */ /* {{{ proto null|boolean WriteConcern::getJournal() Returns the WriteConcern "journal" option */ PHP_METHOD(WriteConcern, getJournal) { php_phongo_writeconcern_t *intern; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_WRITECONCERN_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } if (intern->write_concern->journal != MONGOC_WRITE_CONCERN_JOURNAL_DEFAULT) { RETURN_BOOL(mongoc_write_concern_get_journal(intern->write_concern)); } RETURN_NULL(); } /* }}} */ /** * Value object for write concern used in issuing write operations. */ /* {{{ MongoDB\Driver\WriteConcern */ ZEND_BEGIN_ARG_INFO_EX(ai_WriteConcern___construct, 0, 0, 1) ZEND_ARG_INFO(0, w) ZEND_ARG_INFO(0, wtimeout) ZEND_ARG_INFO(0, journal) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_WriteConcern_getW, 0, 0, 0) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_WriteConcern_getWtimeout, 0, 0, 0) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_WriteConcern_getJournal, 0, 0, 0) ZEND_END_ARG_INFO(); static zend_function_entry php_phongo_writeconcern_me[] = { PHP_ME(WriteConcern, __construct, ai_WriteConcern___construct, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(WriteConcern, getW, ai_WriteConcern_getW, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(WriteConcern, getWtimeout, ai_WriteConcern_getWtimeout, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(WriteConcern, getJournal, ai_WriteConcern_getJournal, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_FE_END }; /* }}} */ /* {{{ php_phongo_writeconcern_t object handlers */ static void php_phongo_writeconcern_free_object(phongo_free_object_arg *object TSRMLS_DC) /* {{{ */ { php_phongo_writeconcern_t *intern = Z_OBJ_WRITECONCERN(object); zend_object_std_dtor(&intern->std TSRMLS_CC); if (intern->write_concern) { mongoc_write_concern_destroy(intern->write_concern); } #if PHP_VERSION_ID < 70000 efree(intern); #endif } /* }}} */ phongo_create_object_retval php_phongo_writeconcern_create_object(zend_class_entry *class_type TSRMLS_DC) /* {{{ */ { php_phongo_writeconcern_t *intern = NULL; intern = PHONGO_ALLOC_OBJECT_T(php_phongo_writeconcern_t, class_type); zend_object_std_init(&intern->std, class_type TSRMLS_CC); object_properties_init(&intern->std, class_type); #if PHP_VERSION_ID >= 70000 intern->std.handlers = &php_phongo_handler_writeconcern; return &intern->std; #else { zend_object_value retval; retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_writeconcern_free_object, NULL TSRMLS_CC); retval.handlers = &php_phongo_handler_writeconcern; return retval; } #endif } /* }}} */ HashTable *php_phongo_writeconcern_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */ { #if PHP_VERSION_ID >= 70000 zval retval; #else zval retval = zval_used_for_init; #endif const mongoc_write_concern_t *write_concern = phongo_write_concern_from_zval(object TSRMLS_CC); *is_temp = 1; php_phongo_write_concern_to_zval(&retval, write_concern); return Z_ARRVAL(retval); } /* }}} */ /* }}} */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(WriteConcern) { zend_class_entry ce; (void)type;(void)module_number; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver", "WriteConcern", php_phongo_writeconcern_me); php_phongo_writeconcern_ce = zend_register_internal_class(&ce TSRMLS_CC); php_phongo_writeconcern_ce->create_object = php_phongo_writeconcern_create_object; PHONGO_CE_INIT(php_phongo_writeconcern_ce); memcpy(&php_phongo_handler_writeconcern, phongo_get_std_object_handlers(), sizeof(zend_object_handlers)); php_phongo_handler_writeconcern.get_debug_info = php_phongo_writeconcern_get_debug_info; #if PHP_VERSION_ID >= 70000 php_phongo_handler_writeconcern.free_obj = php_phongo_writeconcern_free_object; php_phongo_handler_writeconcern.offset = XtOffsetOf(php_phongo_writeconcern_t, std); #endif zend_declare_class_constant_stringl(php_phongo_writeconcern_ce, ZEND_STRL("MAJORITY"), ZEND_STRL(PHONGO_WRITE_CONCERN_W_MAJORITY) TSRMLS_CC); return SUCCESS; } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mongodb-1.1.5/src/MongoDB/WriteConcernError.c0000664000175000017500000001577412673034026020660 0ustar jmikolajmikola/* +---------------------------------------------------------------------------+ | PHP Driver for MongoDB | +---------------------------------------------------------------------------+ | Copyright 2013-2015 MongoDB, Inc. | | | | Licensed under the Apache License, Version 2.0 (the "License"); | | you may not use this file except in compliance with the License. | | You may obtain a copy of the License at | | | | http://www.apache.org/licenses/LICENSE-2.0 | | | | Unless required by applicable law or agreed to in writing, software | | distributed under the License is distributed on an "AS IS" BASIS, | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | See the License for the specific language governing permissions and | | limitations under the License. | +---------------------------------------------------------------------------+ | Copyright (c) 2014-2015 MongoDB, Inc. | +---------------------------------------------------------------------------+ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif /* External libs */ #include #include /* PHP Core stuff */ #include #include #include #include #include /* Our Compatability header */ #include "phongo_compat.h" /* Our stuffz */ #include "php_phongo.h" #include "php_bson.h" PHONGO_API zend_class_entry *php_phongo_writeconcernerror_ce; zend_object_handlers php_phongo_handler_writeconcernerror; /* {{{ proto integer WriteConcernError::getCode() Returns the MongoDB error code */ PHP_METHOD(WriteConcernError, getCode) { php_phongo_writeconcernerror_t *intern; intern = Z_WRITECONCERNERROR_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } RETURN_LONG(intern->code); } /* }}} */ /* {{{ proto mixed WriteConcernError::getInfo() Returns additional metadata for the error */ PHP_METHOD(WriteConcernError, getInfo) { php_phongo_writeconcernerror_t *intern; intern = Z_WRITECONCERNERROR_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } if (!Z_ISUNDEF(intern->info)) { #if PHP_VERSION_ID >= 70000 RETURN_ZVAL(&intern->info, 1, 0); #else RETURN_ZVAL(intern->info, 1, 0); #endif } } /* }}} */ /* {{{ proto string WriteConcernError::getMessage() Returns the actual error message from the server */ PHP_METHOD(WriteConcernError, getMessage) { php_phongo_writeconcernerror_t *intern; intern = Z_WRITECONCERNERROR_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } PHONGO_RETURN_STRING(intern->message); } /* }}} */ /** * Value object for a write concern error. */ /* {{{ MongoDB\Driver\WriteConcernError */ ZEND_BEGIN_ARG_INFO_EX(ai_WriteConcernError_getCode, 0, 0, 0) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_WriteConcernError_getInfo, 0, 0, 0) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_WriteConcernError_getMessage, 0, 0, 0) ZEND_END_ARG_INFO(); static zend_function_entry php_phongo_writeconcernerror_me[] = { PHP_ME(Server, __construct, NULL, ZEND_ACC_FINAL|ZEND_ACC_PRIVATE) PHP_ME(WriteConcernError, getCode, ai_WriteConcernError_getCode, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(WriteConcernError, getInfo, ai_WriteConcernError_getInfo, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(WriteConcernError, getMessage, ai_WriteConcernError_getMessage, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Manager, __wakeUp, NULL, ZEND_ACC_PUBLIC) PHP_FE_END }; /* }}} */ /* {{{ php_phongo_writeconcernerror_t object handlers */ static void php_phongo_writeconcernerror_free_object(phongo_free_object_arg *object TSRMLS_DC) /* {{{ */ { php_phongo_writeconcernerror_t *intern = Z_OBJ_WRITECONCERNERROR(object); zend_object_std_dtor(&intern->std TSRMLS_CC); if (intern->message) { efree(intern->message); } if (!Z_ISUNDEF(intern->info)) { zval_ptr_dtor(&intern->info); } #if PHP_VERSION_ID < 70000 efree(intern); #endif } /* }}} */ phongo_create_object_retval php_phongo_writeconcernerror_create_object(zend_class_entry *class_type TSRMLS_DC) /* {{{ */ { php_phongo_writeconcernerror_t *intern = NULL; intern = PHONGO_ALLOC_OBJECT_T(php_phongo_writeconcernerror_t, class_type); zend_object_std_init(&intern->std, class_type TSRMLS_CC); object_properties_init(&intern->std, class_type); #if PHP_VERSION_ID >= 70000 intern->std.handlers = &php_phongo_handler_writeconcernerror; return &intern->std; #else { zend_object_value retval; retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_writeconcernerror_free_object, NULL TSRMLS_CC); retval.handlers = &php_phongo_handler_writeconcernerror; return retval; } #endif } /* }}} */ HashTable *php_phongo_writeconcernerror_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */ { php_phongo_writeconcernerror_t *intern; #if PHP_VERSION_ID >= 70000 zval retval; #else zval retval = zval_used_for_init; #endif *is_temp = 1; intern = Z_WRITECONCERNERROR_OBJ_P(object); array_init_size(&retval, 3); ADD_ASSOC_STRING(&retval, "message", intern->message); ADD_ASSOC_LONG_EX(&retval, "code", intern->code); if (!Z_ISUNDEF(intern->info)) { #if PHP_VERSION_ID >= 70000 Z_ADDREF(intern->info); ADD_ASSOC_ZVAL_EX(&retval, "info", &intern->info); #else Z_ADDREF_P(intern->info); ADD_ASSOC_ZVAL_EX(&retval, "info", intern->info); #endif } else { ADD_ASSOC_NULL_EX(&retval, "info"); } return Z_ARRVAL(retval); } /* }}} */ /* }}} */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(WriteConcernError) { zend_class_entry ce; (void)type;(void)module_number; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver", "WriteConcernError", php_phongo_writeconcernerror_me); php_phongo_writeconcernerror_ce = zend_register_internal_class(&ce TSRMLS_CC); php_phongo_writeconcernerror_ce->create_object = php_phongo_writeconcernerror_create_object; PHONGO_CE_INIT(php_phongo_writeconcernerror_ce); memcpy(&php_phongo_handler_writeconcernerror, phongo_get_std_object_handlers(), sizeof(zend_object_handlers)); php_phongo_handler_writeconcernerror.get_debug_info = php_phongo_writeconcernerror_get_debug_info; #if PHP_VERSION_ID >= 70000 php_phongo_handler_writeconcernerror.free_obj = php_phongo_writeconcernerror_free_object; php_phongo_handler_writeconcernerror.offset = XtOffsetOf(php_phongo_writeconcernerror_t, std); #endif return SUCCESS; } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mongodb-1.1.5/src/MongoDB/WriteError.c0000664000175000017500000001626012673034026017337 0ustar jmikolajmikola/* +---------------------------------------------------------------------------+ | PHP Driver for MongoDB | +---------------------------------------------------------------------------+ | Copyright 2013-2015 MongoDB, Inc. | | | | Licensed under the Apache License, Version 2.0 (the "License"); | | you may not use this file except in compliance with the License. | | You may obtain a copy of the License at | | | | http://www.apache.org/licenses/LICENSE-2.0 | | | | Unless required by applicable law or agreed to in writing, software | | distributed under the License is distributed on an "AS IS" BASIS, | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | See the License for the specific language governing permissions and | | limitations under the License. | +---------------------------------------------------------------------------+ | Copyright (c) 2014-2015 MongoDB, Inc. | +---------------------------------------------------------------------------+ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif /* External libs */ #include #include /* PHP Core stuff */ #include #include #include #include #include /* Our Compatability header */ #include "phongo_compat.h" /* Our stuffz */ #include "php_phongo.h" #include "php_bson.h" PHONGO_API zend_class_entry *php_phongo_writeerror_ce; zend_object_handlers php_phongo_handler_writeerror; /* {{{ proto integer WriteError::getCode() Returns the MongoDB error code */ PHP_METHOD(WriteError, getCode) { php_phongo_writeerror_t *intern; intern = Z_WRITEERROR_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } RETURN_LONG(intern->code); } /* }}} */ /* {{{ proto integer WriteError::getIndex() Returns the Bulk index where this WriteError occurred in */ PHP_METHOD(WriteError, getIndex) { php_phongo_writeerror_t *intern; intern = Z_WRITEERROR_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } RETURN_LONG(intern->index); } /* }}} */ /* {{{ proto string WriteError::getMessage() Returns the actual error message from the server */ PHP_METHOD(WriteError, getMessage) { php_phongo_writeerror_t *intern; intern = Z_WRITEERROR_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } PHONGO_RETURN_STRING(intern->message); } /* }}} */ /* {{{ proto mixed WriteError::getInfo() Returns additional metadata for the error */ PHP_METHOD(WriteError, getInfo) { php_phongo_writeerror_t *intern; intern = Z_WRITEERROR_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } if (!Z_ISUNDEF(intern->info)) { #if PHP_VERSION_ID >= 70000 RETURN_ZVAL(&intern->info, 1, 0); #else RETURN_ZVAL(intern->info, 1, 0); #endif } } /* }}} */ /** * Value object for a write error (e.g. duplicate key). */ /* {{{ MongoDB\Driver\WriteError */ ZEND_BEGIN_ARG_INFO_EX(ai_WriteError_getCode, 0, 0, 0) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_WriteError_getIndex, 0, 0, 0) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_WriteError_getInfo, 0, 0, 0) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_WriteError_getMessage, 0, 0, 0) ZEND_END_ARG_INFO(); static zend_function_entry php_phongo_writeerror_me[] = { PHP_ME(Server, __construct, NULL, ZEND_ACC_FINAL|ZEND_ACC_PRIVATE) PHP_ME(WriteError, getCode, ai_WriteError_getCode, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(WriteError, getIndex, ai_WriteError_getIndex, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(WriteError, getMessage, ai_WriteError_getMessage, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(WriteError, getInfo, ai_WriteError_getInfo, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Manager, __wakeUp, NULL, ZEND_ACC_PUBLIC) PHP_FE_END }; /* }}} */ /* {{{ php_phongo_writeerror_t object handlers */ static void php_phongo_writeerror_free_object(phongo_free_object_arg *object TSRMLS_DC) /* {{{ */ { php_phongo_writeerror_t *intern = Z_OBJ_WRITEERROR(object); zend_object_std_dtor(&intern->std TSRMLS_CC); if (intern->message) { efree(intern->message); } if (!Z_ISUNDEF(intern->info)) { zval_ptr_dtor(&intern->info); } #if PHP_VERSION_ID < 70000 efree(intern); #endif } /* }}} */ phongo_create_object_retval php_phongo_writeerror_create_object(zend_class_entry *class_type TSRMLS_DC) /* {{{ */ { php_phongo_writeerror_t *intern = NULL; intern = PHONGO_ALLOC_OBJECT_T(php_phongo_writeerror_t, class_type); zend_object_std_init(&intern->std, class_type TSRMLS_CC); object_properties_init(&intern->std, class_type); #if PHP_VERSION_ID >= 70000 intern->std.handlers = &php_phongo_handler_writeerror; return &intern->std; #else { zend_object_value retval; retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_writeerror_free_object, NULL TSRMLS_CC); retval.handlers = &php_phongo_handler_writeerror; return retval; } #endif } /* }}} */ HashTable *php_phongo_writeerror_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */ { php_phongo_writeerror_t *intern; #if PHP_VERSION_ID >= 70000 zval retval; #else zval retval = zval_used_for_init; #endif *is_temp = 1; intern = Z_WRITEERROR_OBJ_P(object); array_init_size(&retval, 3); ADD_ASSOC_STRING(&retval, "message", intern->message); ADD_ASSOC_LONG_EX(&retval, "code", intern->code); ADD_ASSOC_LONG_EX(&retval, "index", intern->index); if (!Z_ISUNDEF(intern->info)) { #if PHP_VERSION_ID >= 70000 Z_ADDREF(intern->info); ADD_ASSOC_ZVAL_EX(&retval, "info", &intern->info); #else Z_ADDREF_P(intern->info); ADD_ASSOC_ZVAL_EX(&retval, "info", intern->info); #endif } else { ADD_ASSOC_NULL_EX(&retval, "info"); } return Z_ARRVAL(retval); } /* }}} */ /* }}} */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(WriteError) { zend_class_entry ce; (void)type;(void)module_number; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver", "WriteError", php_phongo_writeerror_me); php_phongo_writeerror_ce = zend_register_internal_class(&ce TSRMLS_CC); php_phongo_writeerror_ce->create_object = php_phongo_writeerror_create_object; PHONGO_CE_INIT(php_phongo_writeerror_ce); memcpy(&php_phongo_handler_writeerror, phongo_get_std_object_handlers(), sizeof(zend_object_handlers)); php_phongo_handler_writeerror.get_debug_info = php_phongo_writeerror_get_debug_info; #if PHP_VERSION_ID >= 70000 php_phongo_handler_writeerror.free_obj = php_phongo_writeerror_free_object; php_phongo_handler_writeerror.offset = XtOffsetOf(php_phongo_writeerror_t, std); #endif return SUCCESS; } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mongodb-1.1.5/src/MongoDB/WriteResult.c0000664000175000017500000004046612673034026017531 0ustar jmikolajmikola/* +---------------------------------------------------------------------------+ | PHP Driver for MongoDB | +---------------------------------------------------------------------------+ | Copyright 2013-2015 MongoDB, Inc. | | | | Licensed under the Apache License, Version 2.0 (the "License"); | | you may not use this file except in compliance with the License. | | You may obtain a copy of the License at | | | | http://www.apache.org/licenses/LICENSE-2.0 | | | | Unless required by applicable law or agreed to in writing, software | | distributed under the License is distributed on an "AS IS" BASIS, | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | See the License for the specific language governing permissions and | | limitations under the License. | +---------------------------------------------------------------------------+ | Copyright (c) 2014-2015 MongoDB, Inc. | +---------------------------------------------------------------------------+ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif /* External libs */ #include #include #include /* PHP Core stuff */ #include #include #include #include #include /* Our Compatability header */ #include "phongo_compat.h" /* Our stuffz */ #include "php_phongo.h" #include "php_bson.h" PHONGO_API zend_class_entry *php_phongo_writeresult_ce; zend_object_handlers php_phongo_handler_writeresult; /* {{{ proto integer WriteResult::getInsertedCount() Returns the number of documents that were inserted */ PHP_METHOD(WriteResult, getInsertedCount) { php_phongo_writeresult_t *intern; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_WRITERESULT_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } RETURN_LONG(intern->write_result.nInserted); } /* }}} */ /* {{{ proto integer WriteResult::getMatchedCount() Returns the number of documents that matched the update criteria */ PHP_METHOD(WriteResult, getMatchedCount) { php_phongo_writeresult_t *intern; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_WRITERESULT_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } RETURN_LONG(intern->write_result.nMatched); } /* }}} */ /* {{{ proto integer|null WriteResult::getModifiedCount() Returns the number of documents that were actually modified by an update */ PHP_METHOD(WriteResult, getModifiedCount) { php_phongo_writeresult_t *intern; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_WRITERESULT_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } if (intern->write_result.omit_nModified) { RETURN_NULL(); } RETURN_LONG(intern->write_result.nModified); } /* }}} */ /* {{{ proto integer WriteResult::getDeletedCount() Returns the number of documents that were deleted */ PHP_METHOD(WriteResult, getDeletedCount) { php_phongo_writeresult_t *intern; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_WRITERESULT_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } RETURN_LONG(intern->write_result.nRemoved); } /* }}} */ /* {{{ proto integer WriteResult::getUpsertedCount() Returns the number of documents that were upserted */ PHP_METHOD(WriteResult, getUpsertedCount) { php_phongo_writeresult_t *intern; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_WRITERESULT_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } RETURN_LONG(intern->write_result.nUpserted); } /* }}} */ /* {{{ proto MongoDB\Driver\Server WriteResult::getServer() Returns the Server from which the result originated */ PHP_METHOD(WriteResult, getServer) { php_phongo_writeresult_t *intern; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_WRITERESULT_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } phongo_server_init(return_value, intern->client, intern->server_id TSRMLS_CC); } /* }}} */ /* {{{ proto array WriteResult::getUpsertedIds() Returns the identifiers generated by the server for upsert operations. */ PHP_METHOD(WriteResult, getUpsertedIds) { php_phongo_writeresult_t *intern; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_WRITERESULT_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } array_init(return_value); if (!bson_empty0(&intern->write_result.upserted)) { bson_iter_t iter; bson_iter_init(&iter, &intern->write_result.upserted); while (bson_iter_next(&iter)) { int32_t index; bson_iter_t outer; if (!BSON_ITER_HOLDS_DOCUMENT(&iter) || !bson_iter_recurse(&iter, &outer)) { continue; } if (!bson_iter_find(&outer, "index") || !BSON_ITER_HOLDS_INT32(&outer)) { continue; } index = bson_iter_int32(&outer); if (!bson_iter_find(&outer, "_id")) { continue; } if (BSON_ITER_HOLDS_OID(&outer)) { #if PHP_VERSION_ID >= 70000 zval zid; php_phongo_objectid_new_from_oid(&zid, bson_iter_oid(&outer) TSRMLS_CC); add_index_zval(return_value, index, &zid); #else zval *zid = NULL; MAKE_STD_ZVAL(zid); php_phongo_objectid_new_from_oid(zid, bson_iter_oid(&outer) TSRMLS_CC); add_index_zval(return_value, index, zid); #endif } else if (BSON_ITER_HOLDS_INT32(&outer)) { int32_t val = bson_iter_int32(&outer); add_index_long(return_value, index, val); } else if (BSON_ITER_HOLDS_INT64(&outer)) { int64_t val = bson_iter_int64(&outer); ADD_INDEX_INT64(return_value, index, val); } } } } /* }}} */ /* {{{ proto WriteConcernError WriteResult::getWriteConcernError() Return any write concern error that occurred */ PHP_METHOD(WriteResult, getWriteConcernError) { php_phongo_writeresult_t *intern; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_WRITERESULT_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } if (!bson_empty0(&intern->write_result.writeConcernErrors)) { bson_iter_t iter; bson_iter_init(&iter, &intern->write_result.writeConcernErrors); while (bson_iter_next(&iter)) { bson_t cbson; uint32_t len; const uint8_t *data; if (!BSON_ITER_HOLDS_DOCUMENT(&iter)) { continue; } bson_iter_document(&iter, &len, &data); if (!bson_init_static(&cbson, data, len)) { continue; } object_init_ex(return_value, php_phongo_writeconcernerror_ce); if (!phongo_writeconcernerror_init(return_value, &cbson TSRMLS_CC)) { #if PHP_VERSION_ID >= 70000 zval_ptr_dtor(return_value); #else zval_ptr_dtor(&return_value); #endif } return; } } } /* }}} */ /* {{{ proto WriteError[] WriteResult::getWriteErrors() Returns any write errors that occurred */ PHP_METHOD(WriteResult, getWriteErrors) { php_phongo_writeresult_t *intern; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_WRITERESULT_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } array_init(return_value); if (!bson_empty0(&intern->write_result.writeErrors)) { bson_iter_t iter; bson_iter_init(&iter, &intern->write_result.writeErrors); while (bson_iter_next(&iter)) { bson_t cbson; uint32_t len; const uint8_t *data; #if PHP_VERSION_ID >= 70000 zval writeerror; #else zval *writeerror = NULL; #endif if (!BSON_ITER_HOLDS_DOCUMENT(&iter)) { continue; } bson_iter_document(&iter, &len, &data); if (!bson_init_static(&cbson, data, len)) { continue; } #if PHP_VERSION_ID >= 70000 object_init_ex(&writeerror, php_phongo_writeerror_ce); if (!phongo_writeerror_init(&writeerror, &cbson TSRMLS_CC)) { zval_ptr_dtor(&writeerror); continue; } add_next_index_zval(return_value, &writeerror); #else MAKE_STD_ZVAL(writeerror); object_init_ex(writeerror, php_phongo_writeerror_ce); if (!phongo_writeerror_init(writeerror, &cbson TSRMLS_CC)) { zval_ptr_dtor(&writeerror); continue; } add_next_index_zval(return_value, writeerror); #endif } } } /* }}} */ /* {{{ proto boolean WriteResult::isAcknowledged() Returns the number of documents that were upserted */ PHP_METHOD(WriteResult, isAcknowledged) { php_phongo_writeresult_t *intern; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) intern = Z_WRITERESULT_OBJ_P(getThis()); if (zend_parse_parameters_none() == FAILURE) { return; } RETURN_BOOL(_mongoc_write_concern_needs_gle(intern->write_concern)); } /* }}} */ /** * Result returned by Server and Manager executeBulkWrite() methods. * * This class may be constructed internally if it will encapsulate a libmongoc * data structure. */ /* {{{ MongoDB\Driver\WriteResult */ ZEND_BEGIN_ARG_INFO_EX(ai_WriteResult_getInsertedCount, 0, 0, 0) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_WriteResult_getMatchedCount, 0, 0, 0) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_WriteResult_getModifiedCount, 0, 0, 0) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_WriteResult_getDeletedCount, 0, 0, 0) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_WriteResult_getUpsertedCount, 0, 0, 0) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_WriteResult_getServer, 0, 0, 0) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_WriteResult_getUpsertedIds, 0, 0, 0) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_WriteResult_getWriteConcernError, 0, 0, 0) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_WriteResult_getWriteErrors, 0, 0, 0) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_WriteResult_isAcknowledged, 0, 0, 0) ZEND_END_ARG_INFO(); static zend_function_entry php_phongo_writeresult_me[] = { PHP_ME(Server, __construct, NULL, ZEND_ACC_FINAL|ZEND_ACC_PRIVATE) PHP_ME(WriteResult, getInsertedCount, ai_WriteResult_getInsertedCount, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(WriteResult, getMatchedCount, ai_WriteResult_getMatchedCount, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(WriteResult, getModifiedCount, ai_WriteResult_getModifiedCount, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(WriteResult, getDeletedCount, ai_WriteResult_getDeletedCount, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(WriteResult, getUpsertedCount, ai_WriteResult_getUpsertedCount, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(WriteResult, getServer, ai_WriteResult_getServer, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(WriteResult, getUpsertedIds, ai_WriteResult_getUpsertedIds, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(WriteResult, getWriteConcernError, ai_WriteResult_getWriteConcernError, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(WriteResult, getWriteErrors, ai_WriteResult_getWriteErrors, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(WriteResult, isAcknowledged, ai_WriteResult_isAcknowledged, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_ME(Manager, __wakeUp, NULL, ZEND_ACC_PUBLIC) PHP_FE_END }; /* }}} */ /* {{{ php_phongo_writeresult_t object handlers */ static void php_phongo_writeresult_free_object(phongo_free_object_arg *object TSRMLS_DC) /* {{{ */ { php_phongo_writeresult_t *intern = Z_OBJ_WRITERESULT(object); zend_object_std_dtor(&intern->std TSRMLS_CC); _mongoc_write_result_destroy(&intern->write_result); if (intern->write_concern) { mongoc_write_concern_destroy(intern->write_concern); } #if PHP_VERSION_ID < 70000 efree(intern); #endif } /* }}} */ phongo_create_object_retval php_phongo_writeresult_create_object(zend_class_entry *class_type TSRMLS_DC) /* {{{ */ { php_phongo_writeresult_t *intern = NULL; intern = PHONGO_ALLOC_OBJECT_T(php_phongo_writeresult_t, class_type); zend_object_std_init(&intern->std, class_type TSRMLS_CC); object_properties_init(&intern->std, class_type); #if PHP_VERSION_ID >= 70000 intern->std.handlers = &php_phongo_handler_writeresult; return &intern->std; #else { zend_object_value retval; retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, php_phongo_writeresult_free_object, NULL TSRMLS_CC); retval.handlers = &php_phongo_handler_writeresult; return retval; } #endif } /* }}} */ HashTable *php_phongo_writeresult_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */ { php_phongo_writeresult_t *intern; #if PHP_VERSION_ID >= 70000 zval retval; #else zval retval = zval_used_for_init; #endif php_phongo_bson_state state = PHONGO_BSON_STATE_INITIALIZER; bson_iter_t iter; intern = Z_WRITERESULT_OBJ_P(object); *is_temp = 1; array_init_size(&retval, 9); ADD_ASSOC_LONG_EX(&retval, "nInserted", intern->write_result.nInserted); ADD_ASSOC_LONG_EX(&retval, "nMatched", intern->write_result.nMatched); if (intern->write_result.omit_nModified) { ADD_ASSOC_NULL_EX(&retval, "nModified"); } else { ADD_ASSOC_LONG_EX(&retval, "nModified", intern->write_result.nModified); } ADD_ASSOC_LONG_EX(&retval, "nRemoved", intern->write_result.nRemoved); ADD_ASSOC_LONG_EX(&retval, "nUpserted", intern->write_result.nUpserted); /* Use native arrays for debugging output */ state.map.root_type = PHONGO_TYPEMAP_NATIVE_ARRAY; state.map.document_type = PHONGO_TYPEMAP_NATIVE_ARRAY; phongo_bson_to_zval_ex(bson_get_data(&intern->write_result.upserted), intern->write_result.upserted.len, &state); #if PHP_VERSION_ID >= 70000 ADD_ASSOC_ZVAL_EX(&retval, "upsertedIds", &state.zchild); #else ADD_ASSOC_ZVAL_EX(&retval, "upsertedIds", state.zchild); #endif phongo_bson_to_zval_ex(bson_get_data(&intern->write_result.writeErrors), intern->write_result.writeErrors.len, &state); #if PHP_VERSION_ID >= 70000 ADD_ASSOC_ZVAL_EX(&retval, "writeErrors", &state.zchild); #else ADD_ASSOC_ZVAL_EX(&retval, "writeErrors", state.zchild); #endif if (!bson_empty0(&intern->write_result.writeConcernErrors) && bson_iter_init(&iter, &intern->write_result.writeConcernErrors) && bson_iter_next(&iter) && BSON_ITER_HOLDS_DOCUMENT(&iter)) { uint32_t len; const uint8_t *data; bson_iter_document(&iter, &len, &data); phongo_bson_to_zval_ex(data, len, &state); #if PHP_VERSION_ID >= 70000 ADD_ASSOC_ZVAL_EX(&retval, "writeConcernError", &state.zchild); #else ADD_ASSOC_ZVAL_EX(&retval, "writeConcernError", state.zchild); #endif } else { ADD_ASSOC_NULL_EX(&retval, "writeConcernError"); } if (intern->write_concern) { #if PHP_VERSION_ID >= 70000 zval write_concern; php_phongo_write_concern_to_zval(&write_concern, intern->write_concern); #else zval *write_concern = NULL; MAKE_STD_ZVAL(write_concern); php_phongo_write_concern_to_zval(write_concern, intern->write_concern); #endif #if PHP_VERSION_ID >= 70000 ADD_ASSOC_ZVAL_EX(&retval, "writeConcern", &write_concern); #else ADD_ASSOC_ZVAL_EX(&retval, "writeConcern", write_concern); #endif } else { ADD_ASSOC_NULL_EX(&retval, "writeConcern"); } return Z_ARRVAL(retval); } /* }}} */ /* }}} */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(WriteResult) { zend_class_entry ce; (void)type;(void)module_number; INIT_NS_CLASS_ENTRY(ce, "MongoDB\\Driver", "WriteResult", php_phongo_writeresult_me); php_phongo_writeresult_ce = zend_register_internal_class(&ce TSRMLS_CC); php_phongo_writeresult_ce->create_object = php_phongo_writeresult_create_object; PHONGO_CE_INIT(php_phongo_writeresult_ce); memcpy(&php_phongo_handler_writeresult, phongo_get_std_object_handlers(), sizeof(zend_object_handlers)); php_phongo_handler_writeresult.get_debug_info = php_phongo_writeresult_get_debug_info; #if PHP_VERSION_ID >= 70000 php_phongo_handler_writeresult.free_obj = php_phongo_writeresult_free_object; php_phongo_handler_writeresult.offset = XtOffsetOf(php_phongo_writeresult_t, std); #endif return SUCCESS; } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mongodb-1.1.5/src/contrib/php-ssl.c0000664000175000017500000001672112673034026016776 0ustar jmikolajmikola/* +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Authors: Wez Furlong | | Daniel Lowrey | | Chris Wright | +----------------------------------------------------------------------+ */ #ifdef PHP_WIN32 # include "config.w32.h" #else # include #endif #ifdef HAVE_OPENSSL_EXT /* LCOV_EXCL_START */ #include "php-ssl.h" #if defined(NETWARE) || (defined(PHP_WIN32) && defined(_MSC_VER) && _MSC_VER >= 1900) #define timezone _timezone /* timezone is called _timezone in LibC */ #endif int php_mongo_matches_wildcard_name(const char *subjectname, const char *certname) /* {{{ */ { char *wildcard = NULL; int prefix_len, suffix_len, subject_len; if (strcasecmp(subjectname, certname) == 0) { return SUCCESS; } /* wildcard, if present, must only be present in the left-most component */ if (!(wildcard = strchr(certname, '*')) || memchr(certname, '.', wildcard - certname)) { return FAILURE; } /* 1) prefix, if not empty, must match subject */ prefix_len = wildcard - certname; if (prefix_len && strncasecmp(subjectname, certname, prefix_len) != 0) { return FAILURE; } suffix_len = strlen(wildcard + 1); subject_len = strlen(subjectname); if (suffix_len <= subject_len) { /* 2) suffix must match * 3) no . between prefix and suffix **/ if ( strcasecmp(wildcard + 1, subjectname + subject_len - suffix_len) == 0 && memchr(subjectname + prefix_len, '.', subject_len - suffix_len - prefix_len) == NULL) { return SUCCESS; } } return FAILURE; } /* }}} */ int php_mongo_matches_san_list(X509 *peer, const char *subject_name) /* {{{ */ { int i, len; unsigned char *cert_name = NULL; char ipbuffer[64]; GENERAL_NAMES *alt_names = X509_get_ext_d2i(peer, NID_subject_alt_name, 0, 0); int alt_name_count = sk_GENERAL_NAME_num(alt_names); for (i = 0; i < alt_name_count; i++) { GENERAL_NAME *san = sk_GENERAL_NAME_value(alt_names, i); if (san->type == GEN_DNS) { ASN1_STRING_to_UTF8(&cert_name, san->d.dNSName); if ((size_t)ASN1_STRING_length(san->d.dNSName) != strlen((const char*)cert_name)) { OPENSSL_free(cert_name); /* prevent null-byte poisoning*/ continue; } /* accommodate valid FQDN entries ending in "." */ len = strlen((const char*)cert_name); if (len && strcmp((const char *)&cert_name[len-1], ".") == 0) { cert_name[len-1] = '\0'; } if (php_mongo_matches_wildcard_name(subject_name, (const char *)cert_name) == SUCCESS) { OPENSSL_free(cert_name); return SUCCESS; } OPENSSL_free(cert_name); } else if (san->type == GEN_IPADD) { if (san->d.iPAddress->length == 4) { sprintf(ipbuffer, "%d.%d.%d.%d", san->d.iPAddress->data[0], san->d.iPAddress->data[1], san->d.iPAddress->data[2], san->d.iPAddress->data[3] ); if (strcasecmp(subject_name, (const char*)ipbuffer) == 0) { return SUCCESS; } } /* No, we aren't bothering to check IPv6 addresses. Why? * Because IP SAN names are officially deprecated and are * not allowed by CAs starting in 2015. Deal with it. */ } } return FAILURE; } /* }}} */ int php_mongo_matches_common_name(X509 *peer, const char *subject_name TSRMLS_DC) /* {{{ */ { char buf[1024]; X509_NAME *cert_name; int cert_name_len; cert_name = X509_get_subject_name(peer); cert_name_len = X509_NAME_get_text_by_NID(cert_name, NID_commonName, buf, sizeof(buf)); if (cert_name_len == -1) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to locate peer certificate CN"); } else if ((size_t) cert_name_len != strlen(buf)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Peer certificate CN=`%.*s' is malformed", cert_name_len, buf); } else if (php_mongo_matches_wildcard_name(subject_name, buf) == SUCCESS) { return SUCCESS; } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Peer certificate CN=`%.*s' did not match expected CN=`%s'", cert_name_len, buf, subject_name); } return FAILURE; } /* }}} */ time_t php_mongo_asn1_time_to_time_t(ASN1_UTCTIME * timestr TSRMLS_DC) /* {{{ */ { /* This is how the time string is formatted: snprintf(p, sizeof(p), "%02d%02d%02d%02d%02d%02dZ",ts->tm_year%100, ts->tm_mon+1,ts->tm_mday,ts->tm_hour,ts->tm_min,ts->tm_sec); */ time_t ret; struct tm thetime; char * strbuf; char * thestr; long gmadjust = 0; if (ASN1_STRING_type(timestr) != V_ASN1_UTCTIME && ASN1_STRING_type(timestr) != V_ASN1_GENERALIZEDTIME) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "illegal ASN1 data type for timestamp"); return (time_t)-1; } if ((size_t)ASN1_STRING_length(timestr) != strlen((char *)ASN1_STRING_data(timestr))) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "illegal length in timestamp"); return (time_t)-1; } if (ASN1_STRING_length(timestr) < 13) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to parse time string %s correctly", timestr->data); return (time_t)-1; } if (ASN1_STRING_type(timestr) == V_ASN1_GENERALIZEDTIME && ASN1_STRING_length(timestr) < 15) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "unable to parse time string %s correctly", timestr->data); return (time_t)-1; } strbuf = estrdup((char *)ASN1_STRING_data(timestr)); memset(&thetime, 0, sizeof(thetime)); /* we work backwards so that we can use atoi more easily */ thestr = strbuf + ASN1_STRING_length(timestr) - 3; thetime.tm_sec = atoi(thestr); *thestr = '\0'; thestr -= 2; thetime.tm_min = atoi(thestr); *thestr = '\0'; thestr -= 2; thetime.tm_hour = atoi(thestr); *thestr = '\0'; thestr -= 2; thetime.tm_mday = atoi(thestr); *thestr = '\0'; thestr -= 2; thetime.tm_mon = atoi(thestr)-1; *thestr = '\0'; if( ASN1_STRING_type(timestr) == V_ASN1_UTCTIME ) { thestr -= 2; thetime.tm_year = atoi(thestr); if (thetime.tm_year < 68) { thetime.tm_year += 100; } } else if( ASN1_STRING_type(timestr) == V_ASN1_GENERALIZEDTIME ) { thestr -= 4; thetime.tm_year = atoi(thestr) - 1900; } thetime.tm_isdst = -1; ret = mktime(&thetime); #if HAVE_TM_GMTOFF gmadjust = thetime.tm_gmtoff; #else /* ** If correcting for daylight savings time, we set the adjustment to ** the value of timezone - 3600 seconds. Otherwise, we need to overcorrect and ** set the adjustment to the main timezone + 3600 seconds. */ gmadjust = -(thetime.tm_isdst ? (long)timezone - 3600 : (long)timezone + 3600); #endif ret += gmadjust; efree(strbuf); return ret; } /* }}} */ /* LCOV_EXCL_STOP */ #endif /* HAVE_OPENSSL_EXT */ mongodb-1.1.5/src/contrib/php-ssl.h0000664000175000017500000000354312673034026017001 0ustar jmikolajmikola/* +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2015 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Authors: Wez Furlong | | Daniel Lowrey | | Chris Wright | +----------------------------------------------------------------------+ */ #ifndef MONGO_CONTRIB_SSL_H #define MONGO_CONTRIB_SSL_H #ifdef PHP_WIN32 # include "config.w32.h" #else # include #endif #ifdef HAVE_OPENSSL_EXT #include "php.h" #include #include #include int php_mongo_matches_wildcard_name(const char *subjectname, const char *certname); int php_mongo_matches_san_list(X509 *peer, const char *subject_name); int php_mongo_matches_common_name(X509 *peer, const char *subject_name TSRMLS_DC); time_t php_mongo_asn1_time_to_time_t(ASN1_UTCTIME * timestr TSRMLS_DC); #endif /* HAVE_OPENSSL_EXT */ #endif mongodb-1.1.5/src/contrib/php_array_api.h0000664000175000017500000005066112673034026020234 0ustar jmikolajmikola/* +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2013 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Sara Golemon (pollita@php.net) | +----------------------------------------------------------------------+ */ #ifndef PHP_ARRAY_API_H #define PHP_ARRAY_API_H #include "zend.h" #include "zend_execute.h" #include "zend_API.h" #include "zend_operators.h" #include "zend_hash.h" #include "zend_list.h" #ifdef ZEND_ENGINE_3 # define PAA_LENGTH_ADJ(l) (l) # define PAA_SYM_EXISTS zend_symtable_str_exists # define PAA_SYM_DEL zend_symtable_str_del #else # define PAA_LENGTH_ADJ(l) (l+1) # define PAA_SYM_EXISTS zend_symtable_exists # define PAA_SYM_DEL zend_symtable_del #endif /** * All APIs in this file follow a general format: * * php_array_{$verb}{$modifier}_{$type}(zval *zarr, ...) * * $verb is one of: * exists - Boolean check whether the array offset exists * fetch - Retrieve the value at $zarr[$key] * unset - Delete the named offset from the array * * $modifier specifies what type of offset (key) is being used: * - NULL terminated string variable, unknown length * l - NULL terminated string variable, known length * l_safe - String variable of known length, not necessarily NULL terminated * n - Long (integer) offset * c - NULL terminated string literal (e.g. "foo" rather than foo) * z - zval* offset, type should be NULL, BOOL, LONG, DOUBLE, or STRING * * $type is specific to the "fetch" verb: * - Fetch a zval* of any type * bool - Fetch a zend_bool (converting as needed) * long - Fetch a long (converting as needed) * double - Fetch a double (converting as needed) * string - Fetch a string (converting as needed, caller may need to free) * array - Fetch an array (no conversion from other types) * object - Fetch an object (no conversion, type spec optional) * resource - Fetch a resource (no conversion, type spec mandatory) * * See the specific subsection for additional details */ /* isset($zarr[$key]) - Check for the existence of a key within an array * * zend_bool php_array_exists(zval *zarr, const char *key) * zend_bool php_array_existsc(zval *zarr, const char *litstr) * zend_bool php_array_existsl(zval *zarr, const char *key, int key_len) * zend_bool php_array_existsl_safe(zval *zarr, const char *key, int key_len) * zend_bool php_array_existsn(zval *zarr, long idx) * zend_bool php_array_existsz(zval *zarr, zval *key) */ static inline zend_bool php_array_exists(zval *zarr, const char *key) { return PAA_SYM_EXISTS(Z_ARRVAL_P(zarr), key, PAA_LENGTH_ADJ(strlen(key))); } #define php_array_existsc(zarr, litstr) \ PAA_SYM_EXISTS(Z_ARRVAL_P(zarr), litstr, PAA_LENGTH_ADJ(sizeof(litstr) - 1)) #define php_array_existsl(zarr, key, len) \ PAA_SYM_EXISTS(Z_ARRVAL_P(zarr), key, PAA_LENGTH_ADJ(len)) static inline zend_bool php_array_existsl_safe(zval *zarr, const char *key, int key_len) { #ifdef ZEND_ENGINE_3 zend_string *keystr = zend_string_init(key, key_len, 0); zend_bool ret = zend_symtable_exists(Z_ARRVAL_P(zarr), keystr); zend_string_release(keystr); #else char *k = estrndup(key, key_len); zend_bool ret = zend_symtable_exists(Z_ARRVAL_P(zarr), k, key_len + 1); efree(k); #endif return ret; } #define php_array_existsn(zarr, idx) \ zend_hash_index_exists(Z_ARRVAL_P(zarr), idx) static inline zend_bool php_array_existsz(zval *zarr, zval *key) { switch (Z_TYPE_P(key)) { case IS_NULL: return php_array_existsc(zarr, ""); #ifdef ZEND_ENGINE_3 case IS_FALSE: return zend_hash_index_exists(Z_ARRVAL_P(zarr), 0); case IS_TRUE: return zend_hash_index_exists(Z_ARRVAL_P(zarr), 1); #else case IS_BOOL: /* fallthrough */ #endif case IS_LONG: return zend_hash_index_exists(Z_ARRVAL_P(zarr), Z_LVAL_P(key)); case IS_DOUBLE: return zend_hash_index_exists(Z_ARRVAL_P(zarr), zend_dval_to_lval(Z_DVAL_P(key))); case IS_STRING: return php_array_existsl(zarr, Z_STRVAL_P(key), Z_STRLEN_P(key)); default: return 0; } } /* =$zarr[$key] - Fetch a zval (or appropriate type) from an array * * Methods returning pointers yield NULL on key not existing, * others yield 0, false, etc... as appropriate. * Callers needing to distinguish empty scalars from non-existent * scalars should use php_array_exists*() or fetch the zval then convert. * * If the type of the value does not match what is requested * it will be implicitly converted (if possible). * * See each type section for specific prototypes * * php_array_fetch* - Fetch a zval * php_array_fetch*_bool - Fetch a boolean * php_array_fetch*_long - Fetch a long * php_array_fetch*_double - Fetch a double * php_array_fetch*_string - Fetch a string (must be efree()'d by caller) * php_array_fetch*_array - Fetch an array * php_array_fetch*_resource - Fetch a resource or a specific type * php_array_fetch*_object - Fetch an object * * For each result type, there are six key forms: * php_array_fetch_T(zval *zarr, const char *key, ...) * NULL terminated string key * php_array_fetchc_T(zval *zarr, const char *litkey, ...) * String literal key * php_array_fetchl_T(zval *zarr, const char *key, int key_len, ...) * NULL terminated string key of known length * php_array_fetchl_safe_T(zval *zarr, const char *key, int key_len, ...) * String key of known length, may not be NULL terminated * php_array_fetchn_T(zval *zarr, long idx, ...) * Numeric key * php_array_fetchz_T(zval *zarr, zval *key, ...) * zval* key */ /* Fetch zval* * * zval *php_array_fetch(zval *zarr, const char *key) * zval *php_array_fetchl(zval *zarr, const char *key, int key_len) * zval *php_array_fetchl_safe(zval *zarr, const char *key, int key_len) * zval *php_array_fetchn(zval *zarr, long idx) * zval *php_array_fetchc(zval *zarr, const char *litstr) * zval *php_array_fetchz(zval *zarr, zval *key) */ static inline zval *php_array_fetchl(zval *zarr, const char *key, int key_len) { #ifdef ZEND_ENGINE_3 return zend_symtable_str_find(Z_ARRVAL_P(zarr), key, key_len); #else zval **ppzval; if (FAILURE == zend_symtable_find(Z_ARRVAL_P(zarr), key, key_len + 1, (void**)&ppzval)) { return NULL; } return *ppzval; #endif } static inline zval *php_array_fetch(zval *zarr, const char *key) { return php_array_fetchl(zarr, key, strlen(key)); } #define php_array_fetchc(zarr, litstr) php_array_fetchl(zarr, litstr, sizeof(litstr)-1) static inline zval *php_array_fetchl_safe(zval *zarr, const char *key, int key_len) { #ifdef ZEND_ENGINE_3 zend_string *keystr = zend_string_init(key, key_len, 0); zval *ret = zend_symtable_find(Z_ARRVAL_P(zarr), keystr); zend_string_release(keystr); #else char *k = estrndup(key, key_len); zval *ret = php_array_fetchl(zarr, k, key_len); efree(k); #endif return ret; } static inline zval *php_array_fetchn(zval *zarr, long idx) { #ifdef ZEND_ENGINE_3 return zend_hash_index_find(Z_ARRVAL_P(zarr), idx); #else zval **ppzval; if (FAILURE == zend_hash_index_find(Z_ARRVAL_P(zarr), idx, (void**)&ppzval)) { return NULL; } return *ppzval; #endif } static inline zval *php_array_fetchz(zval *zarr, zval *key) { switch (Z_TYPE_P(key)) { case IS_NULL: return php_array_fetchn(zarr, 0); #ifdef ZEND_ENGINE_3 case IS_FALSE: return php_array_fetchn(zarr, 0); case IS_TRUE: return php_array_fetchn(zarr, 1); #else case IS_BOOL: /* fallthrough */ #endif case IS_LONG: return php_array_fetchn(zarr, Z_LVAL_P(key)); case IS_DOUBLE: return php_array_fetchn(zarr, (long)Z_DVAL_P(key)); case IS_STRING: return php_array_fetchl(zarr, Z_STRVAL_P(key), Z_STRLEN_P(key)); default: return NULL; } } #define PHP_ARRAY_FETCH_TYPE_MAP(ctype, ztype) \ static inline ctype php_array_fetch_##ztype(zval *zarr, const char *key) \ { return php_array_zval_to_##ztype(php_array_fetch(zarr, key)); } \ static inline ctype php_array_fetchl_##ztype(zval *zarr, const char *key, int key_len) \ { return php_array_zval_to_##ztype(php_array_fetchl(zarr, key, key_len)); } \ static inline ctype php_array_fetchl_safe_##ztype(zval *zarr, const char *key, int key_len) \ { return php_array_zval_to_##ztype(php_array_fetchl_safe(zarr, key, key_len)); } \ static inline ctype php_array_fetchn_##ztype(zval *zarr, long idx) \ { return php_array_zval_to_##ztype(php_array_fetchn(zarr, idx)); } \ static inline ctype php_array_fetchz_##ztype(zval *zarr, zval *key) \ { return php_array_zval_to_##ztype(php_array_fetchz(zarr, key)); } /* Fetch zend_bool * * zend_bool php_array_fetch_bool(zval *zarr, const char *key) * zend_bool php_array_fetchl_bool(zval *zarr, const char *key, int key_len) * zend_bool php_array_fetchl_safe_bool(zval *zarr, const char *key, int key_len) * zend_bool php_array_fetchn_bool(zval *zarr, long idx) * zend_bool php_array_fetchc_bool(zval *zarr, const char *litstr) * zend_bool php_array_fetchz_bool(zval *zarr, zval *key) */ static inline zend_bool php_array_zval_to_bool(zval *z) { return z && zend_is_true(z); } PHP_ARRAY_FETCH_TYPE_MAP(zend_bool, bool) #define php_array_fetchc_bool(zarr, litstr) \ php_array_zval_to_bool(php_array_fetchc(zarr, litstr)) /* Fetch long * * long php_array_fetch_long(zval *zarr, const char *key) * long php_array_fetchl_long(zval *zarr, const char *key, int key_len) * long php_array_fetchl_safe_long(zval *zarr, const char *key, int key_len) * long php_array_fetchn_long(zval *zarr, long idx) * long php_array_fetchc_long(zval *zarr, const char *litstr) * long php_array_fetchz_long(zval *zarr, zval *key) */ static inline long php_array_zval_to_long(zval *z) { if (!z) { return 0; } switch(Z_TYPE_P(z)) { case IS_NULL: return 0; #ifdef ZEND_ENGINE_3 case IS_FALSE: return 0; case IS_TRUE: return 1; #else case IS_BOOL: return Z_BVAL_P(z); #endif case IS_LONG: return Z_LVAL_P(z); case IS_DOUBLE: return (long)Z_DVAL_P(z); default: { zval c = *z; zval_copy_ctor(&c); convert_to_long(&c); return Z_LVAL(c); } } } PHP_ARRAY_FETCH_TYPE_MAP(long, long) #define php_array_fetchc_long(zarr, litstr) \ php_array_zval_to_long(php_array_fetchc(zarr, litstr)) /* Fetch double * * double php_array_fetch_double(zval *zarr, const char *key) * double php_array_fetchl_double(zval *zarr, const char *key, int key_len) * double php_array_fetchl_safe_double(zval *zarr, const char *key, int key_len) * double php_array_fetchn_double(zval *zarr, long idx) * double php_array_fetchc_double(zval *zarr, const char *litstr) * double php_array_fetchz_double(zval *zarr, zval *key) */ static inline double php_array_zval_to_double(zval *z) { if (!z) { return 0.0; } switch (Z_TYPE_P(z)) { case IS_NULL: return 0.0; #ifdef ZEND_ENGINE_3 case IS_FALSE: return 0.0; case IS_TRUE: return 1.0; #else case IS_BOOL: return (double)Z_BVAL_P(z); #endif case IS_LONG: return (double)Z_LVAL_P(z); case IS_DOUBLE: return Z_DVAL_P(z); default: { zval c = *z; zval_copy_ctor(&c); convert_to_double(&c); return Z_DVAL(c); } } } PHP_ARRAY_FETCH_TYPE_MAP(double, double) #define php_array_fetchc_double(zarr, litstr) \ php_array_zval_to_double(php_array_fetchc(zarr, litstr)) /* Fetch string * * If the pfree is set to 1 on exit, then the return value is owned by the caller * and must be efree()'d once it is no longer in use. * * plen is populated with the binary safe length of the string returned. * * char *php_array_fetch_string(zval *zarr, const char *key, int *plen, zend_bool *pfree) * char *php_array_fetchl_string(zval *zarr, const char *key, int key_len, int *plen, zend_bool *pfree) * char *php_array_fetchl_safe_string(zval *zarr, const char *key, int key_len, int *plen, zend_bool *pfree) * char *php_array_fetchn_string(zval *zarr, long idx, int *plen, zend_bool *pfree) * char *php_array_fetchc_string(zval *zarr, const char *litstr, int *plen, zend_bool *pfree) * char *php_array_fetchz_string(zval *zarr, zval *key, int *plen, zend_bool *pfree) */ static inline char *php_array_zval_to_string(zval *z, int *plen, zend_bool *pfree) { *plen = 0; *pfree = 0; if (!z) { return NULL; } *pfree = 1; switch (Z_TYPE_P(z)) { case IS_NULL: *pfree = 0; return (char *)""; case IS_STRING: *pfree = 0; *plen = Z_STRLEN_P(z); return Z_STRVAL_P(z); default: { zval c = *z; zval_copy_ctor(&c); convert_to_string(&c); *plen = Z_STRLEN(c); return Z_STRVAL(c); } } } #define php_array_fetch_string(zarr, key, plen, pfree) \ php_array_zval_to_string(php_array_fetch(zarr, key), plen, pfree) #define php_array_fetchl_string(zarr, key, key_len, plen, pfree) \ php_array_zval_to_string(php_array_fetchl(zarr, key, key_len), plen, pfree) #define php_array_fetchl_safe_string(zarr, key, key_len, plen, pfree) \ php_array_zval_to_string(php_array_fetchl_safe(zarr, key, key_len), plen, pfree) #define php_array_fetchn_string(zarr, idx, plen, pfree) \ php_array_zval_to_string(php_array_fetchn(zarr, idx), plen, pfree) #define php_array_fetchc_string(zarr, litstr, plen, pfree) \ php_array_zval_to_string(php_array_fetchc(zarr, litstr), plen, pfree) #define php_array_fetchz_string(zarr, key, plen, pfree) \ php_array_zval_to_string(php_array_fetchz(zarr, key), plen, pfree) /* Fetch array * * No implicit conversion is performed. * * If the value is an array, then that zval is returned, * otherwise NULL is returned. * * zval *php_array_fetch_array(zval *zarr, const char *key) * zval *php_array_fetchl_array(zval *zarr, const char *key, int key_len) * zval *php_array_fetchl_safe_array(zval *zarr, const char *key, int key_len) * zval *php_array_fetchn_array(zval *zarr, long idx) * zval *php_array_fetchc_array(zval *zarr, const char *litstr) * zval *php_array_fetchz_array(zval *zarr, zval *key) */ static inline zval *php_array_zval_to_array(zval *zarr) { return (zarr && (Z_TYPE_P(zarr) == IS_ARRAY)) ? zarr : NULL; } PHP_ARRAY_FETCH_TYPE_MAP(zval*, array) #define php_array_fetchc_array(zarr, litstr) \ php_array_zval_to_array(php_array_fetchc(zarr, litstr)) /* count($arr) - Count number of elements in the array * * int php_array_count(zval *arr) */ #define php_array_count(zarr) zend_hash_num_elements(Z_ARRVAL_P(zarr)) /* Fetch resource * * No implicit conversion is performed. * * If the value is a resource of the named type, * then the pointer for it is returned, * otherwise NULL is returned. * * To test for multiple resource types (e.g. 'stream' and 'persistent stream') * Fetch a generic zval* and use Zend's ZEND_FETCH_RESOURCE() macro. * * zval *php_array_fetch_resource(zval *zarr, const char *key, int le) * zval *php_array_fetchl_resource(zval *zarr, const char *key, int key_len, int le) * zval *php_array_fetchl_safe_resource(zval *zarr, const char *key, int key_len, int le) * zval *php_array_fetchn_resource(zval *zarr, long idx, int le) * zval *php_array_fetchc_resource(zval *zarr, const char *litstr, int le) * zval *php_array_fetchz_resource(zval *zarr, zval *key, int le) */ static inline void *php_array_zval_to_resource(zval *z, int le TSRMLS_DC) { #ifdef ZEND_ENGINE_3 return zend_fetch_resource_ex(z, NULL, le); #else void *ret; int rtype; if (!z || Z_TYPE_P(z) != IS_RESOURCE) { return NULL; } ret = zend_list_find(Z_RESVAL_P(z), &rtype); if (!ret || (rtype != le)) { return NULL; } return ret; #endif } #define php_array_fetch_resource(zarr, key, le) \ php_array_zval_to_resource(php_array_fetch(zarr, key), le TSRMLS_CC) #define php_array_fetchl_resource(zarr, key, key_len, le) \ php_array_zval_to_resource(php_array_fetchl(zarr, key, key_len), le TSRMLS_CC) #define php_array_fetchl_safe_resource(zarr, key, key_len, le) \ php_array_zval_to_resource(php_array_fetchl_safe(zarr, key, key_len), le TSRMLS_CC) #define php_array_fetchn_resource(zarr, idx, le) \ php_array_zval_to_resource(php_array_fetchn(zarr, idx), le TSRMLS_CC) #define php_array_fetchc_resource(zarr, litstr, le) \ php_array_zval_to_resource(php_array_fetchc(zarr, litstr), le TSRMLS_CC) #define php_array_fetchz_resource(zarr, key, le) \ php_array_zval_to_resource(php_array_fetchz(zarr, key), le TSRMLS_CC) /* Fetch Object * * Fetch an object of a specific or non-specific type (pass ce == NULL) * * No implicit conversion is performed * * zval *php_array_fetch_object(zval *zarr, const char *key, zend_class_entry *ce) * zval *php_array_fetchl_object(zval *zarr, const char *key, int key_len, zend_class_entry *ce) * zval *php_array_fetchl_safe_object(zval *zarr, const char *key, int key_len, zend_class_entry *ce) * zval *php_array_fetchn_object(zval *zarr, long idx, zend_class_entry *ce) * zval *php_array_fetchc_object(zval *zarr, const char *litstr, zend_class_entry *ce) * zval *php_array_fetchz_object(zval *zarr, zval *key, zend_class_entry *ce) */ static inline zval *php_array_zval_to_object(zval *z, zend_class_entry *ce TSRMLS_DC) { return (z && (Z_TYPE_P(z) == IS_OBJECT) && ((!ce) || instanceof_function(Z_OBJCE_P(z), ce TSRMLS_CC))) ? z : NULL; } #define php_array_fetch_object(zarr, key, ce) \ php_array_zval_to_object(php_array_fetch(zarr, key), ce TSRMLS_CC) #define php_array_fetchl_object(zarr, key, len, ce) \ php_array_zval_to_object(php_array_fetchl(zarr, key, len), ce TSRMLS_CC) #define php_array_fetchl_safe_object(zarr, key, len, ce) \ php_array_zval_to_object(php_array_fetchl_safe(zarr, key, len), ce TSRMLS_CC) #define php_array_fetchn_object(zarr, idx, ce) \ php_array_zval_to_object(php_array_fetchn(zarr, idx), ce TSRMLS_CC) #define php_array_fetchc_object(zarr, litstr, ce) \ php_array_zval_to_object(php_array_fetchc(zarr, litstr), ce TSRMLS_CC) #define php_array_fetchz_object(zarr, key, ce) \ php_array_zval_to_object(php_array_fetchz(zarr, key), ce TSRMLS_CC) /* unset($zarr[$key]) - Erase a key from an array * * void php_array_unset(zval *zarr, const char *key) * void php_array_unsetl(zval *zarr, const char *key, int key_len) * void php_array_unsetl_safe(zval *zarr, const char *key, int key_len) * void php_array_unsetn(zval *zarr, long idx) * void php_array_unsetc(zval *zarr, const char *litstr) * void php_array_unsetz(zval *zarr, zval *key) */ static inline void php_array_unset(zval *zarr, const char *key) { PAA_SYM_DEL(Z_ARRVAL_P(zarr), key, PAA_LENGTH_ADJ(strlen(key))); } #define php_array_unsetl(zarr, key, len) \ PAA_SYM_DEL(Z_ARRVAL_P(zarr), key, PAA_LENGTH_ADJ(len)) static inline void php_array_unsetl_safe(zval *zarr, const char *key, int key_len) { char *k = estrndup(key, key_len); PAA_SYM_DEL(Z_ARRVAL_P(zarr), k, PAA_LENGTH_ADJ(key_len)); efree(k); } #define php_array_unsetn(zarr, idx) \ zend_symtable_index_del(Z_ARRVAL_P(zarr), idx) #ifdef ZEND_ENGINE_3 # define php_array_unsetc(zarr, litstr) \ zend_symtable_str_del(Z_ARRVAL_P(zarr), litstr, PAA_LENGTH_ADJ(sizeof(litstr) - 1)) #else # define php_array_unsetc(zarr, litstr) \ zend_symtable_del(Z_ARRVAL_P(zarr), litstr, PAA_LENGTH_ADJ(sizeof(litstr) - 1)) #endif static inline void php_array_unsetz(zval *zarr, zval *key) { switch (Z_TYPE_P(key)) { case IS_NULL: zend_hash_index_del(Z_ARRVAL_P(zarr), 0); return; #ifdef ZEND_ENGINE_3 case IS_FALSE: zend_hash_index_del(Z_ARRVAL_P(zarr), 0); return; case IS_TRUE: zend_hash_index_del(Z_ARRVAL_P(zarr), 1); return; #else case IS_BOOL: /* fallthrough */ #endif case IS_LONG: zend_hash_index_del(Z_ARRVAL_P(zarr), Z_LVAL_P(key)); return; case IS_DOUBLE: zend_hash_index_del(Z_ARRVAL_P(zarr), (long)Z_DVAL_P(key)); break; case IS_STRING: php_array_unsetl(zarr, Z_STRVAL_P(key), Z_STRLEN_P(key)); break; } } #endif /* PHP_ARRAY_API_H */ mongodb-1.1.5/src/libbson/build/autotools/m4/ac_check_typedef.m40000664000175000017500000000264012673034026024401 0ustar jmikolajmikoladnl @synopsis AC_CHECK_TYPEDEF_(TYPEDEF, HEADER [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]) dnl dnl check if the given typedef-name is recognized as a type. The trick dnl is to use a sizeof(TYPEDEF) and see if the compiler is happy with dnl that. dnl dnl this can be thought of as a mixture of dnl AC_CHECK_TYPE(TYPEDEF,DEFAULT) and dnl AC_CHECK_LIB(LIBRARY,FUNCTION,ACTION-IF-FOUND,ACTION-IF-NOT-FOUND) dnl dnl a convenience macro AC_CHECK_TYPEDEF_ is provided that will not dnl emit any message to the user - it just executes one of the actions. dnl dnl @category C dnl @author Guido U. Draheim dnl @version 2006-10-13 dnl @license GPLWithACException AC_DEFUN([AC_CHECK_TYPEDEF_], [dnl ac_lib_var=`echo $1['_']$2 | sed 'y%./+-%__p_%'` AC_CACHE_VAL(ac_cv_lib_$ac_lib_var, [ eval "ac_cv_type_$ac_lib_var='not-found'" ac_cv_check_typedef_header=`echo ifelse([$2], , stddef.h, $2)` AC_TRY_COMPILE( [#include <$ac_cv_check_typedef_header>], [int x = sizeof($1); x = x;], eval "ac_cv_type_$ac_lib_var=yes" , eval "ac_cv_type_$ac_lib_var=no" ) if test `eval echo '$ac_cv_type_'$ac_lib_var` = "no" ; then ifelse([$4], , :, $4) else ifelse([$3], , :, $3) fi ])]) dnl AC_CHECK_TYPEDEF(TYPEDEF, HEADER [, ACTION-IF-FOUND, dnl [, ACTION-IF-NOT-FOUND ]]) AC_DEFUN([AC_CHECK_TYPEDEF], [dnl AC_MSG_CHECKING([for $1 in $2]) AC_CHECK_TYPEDEF_($1,$2,AC_MSG_RESULT(yes),AC_MSG_RESULT(no))dnl ]) mongodb-1.1.5/src/libbson/build/autotools/m4/ac_compile_check_sizeof.m40000664000175000017500000000156612673034026025756 0ustar jmikolajmikolaAC_DEFUN([AC_COMPILE_CHECK_SIZEOF], [changequote(<<, >>)dnl dnl The name to #define. define(<<AC_TYPE_NAME>>, translit(sizeof_$1, [a-z *], [A-Z_P]))dnl dnl The cache variable name. define(<<AC_CV_NAME>>, translit(ac_cv_sizeof_$1, [ *], [_p]))dnl changequote([, ])dnl AC_MSG_CHECKING(size of $1) AC_CACHE_VAL(AC_CV_NAME, [for ac_size in 4 8 1 2 16 $2 ; do # List sizes in rough order of prevalence. AC_TRY_COMPILE([#include "confdefs.h" #include <sys/types.h> $2 ], [switch (0) case 0: case (sizeof ($1) == $ac_size):;], AC_CV_NAME=$ac_size) if test x$AC_CV_NAME != x ; then break; fi done ]) if test x$AC_CV_NAME = x ; then AC_MSG_ERROR([cannot determine a size for $1]) fi AC_MSG_RESULT($AC_CV_NAME) AC_DEFINE_UNQUOTED(AC_TYPE_NAME, $AC_CV_NAME, [The number of bytes in type $1]) undefine([AC_TYPE_NAME])dnl undefine([AC_CV_NAME])dnl ]) mongodb-1.1.5/src/libbson/build/autotools/m4/ac_create_stdint_h.m40000664000175000017500000003662212673034026024752 0ustar jmikolajmikoladnl @synopsis AC_CREATE_STDINT_H [( HEADER-TO-GENERATE [, HEDERS-TO-CHECK])] dnl dnl the "ISO C9X: 7.18 Integer types " section requires the dnl existence of an include file that defines a set of dnl typedefs, especially uint8_t,int32_t,uintptr_t. Many older dnl installations will not provide this file, but some will have the dnl very same definitions in . In other enviroments we can dnl use the inet-types in which would define the typedefs dnl int8_t and u_int8_t respectivly. dnl dnl This macros will create a local "_stdint.h" or the headerfile given dnl as an argument. In many cases that file will just have a singular dnl "#include " or "#include " statement, while dnl in other environments it will provide the set of basic 'stdint's dnl defined: dnl int8_t,uint8_t,int16_t,uint16_t,int32_t,uint32_t,intptr_t,uintptr_t dnl int_least32_t.. int_fast32_t.. intmax_t which may or may not rely dnl on the definitions of other files, or using the dnl AC_COMPILE_CHECK_SIZEOF macro to determine the actual sizeof each dnl type. dnl dnl if your header files require the stdint-types you will want to dnl create an installable file mylib-int.h that all your other dnl installable header may include. So if you have a library package dnl named "mylib", just use dnl dnl AC_CREATE_STDINT_H(mylib-int.h) dnl dnl in configure.in and go to install that very header file in dnl Makefile.am along with the other headers (mylib.h) - and the dnl mylib-specific headers can simply use "#include " to dnl obtain the stdint-types. dnl dnl Remember, if the system already had a valid , the dnl generated file will include it directly. No need for fuzzy dnl HAVE_STDINT_H things... dnl dnl (note also the newer variant AX_CREATE_STDINT_H of this macro) dnl dnl @category C dnl @author Guido U. Draheim dnl @version 2003-05-21 dnl @license GPLWithACException AC_DEFUN([AC_CREATE_STDINT_H], [# ------ AC CREATE STDINT H ------------------------------------- AC_MSG_CHECKING([for stdint-types....]) ac_stdint_h=`echo ifelse($1, , _stdint.h, $1)` if test "$ac_stdint_h" = "stdint.h" ; then AC_MSG_RESULT("(are you sure you want them in ./stdint.h?)") elif test "$ac_stdint_h" = "inttypes.h" ; then AC_MSG_RESULT("(are you sure you want them in ./inttypes.h?)") else AC_MSG_RESULT("(putting them into $ac_stdint_h)") mkdir -p $(dirname "$ac_stdint_h") fi inttype_headers=`echo inttypes.h sys/inttypes.h sys/inttypes.h $2 \ | sed -e 's/,/ /g'` ac_cv_header_stdint_x="no-file" ac_cv_header_stdint_o="no-file" ac_cv_header_stdint_u="no-file" for i in stdint.h $inttype_headers ; do unset ac_cv_type_uintptr_t unset ac_cv_type_uint64_t _AC_CHECK_TYPE_NEW(uintptr_t,[ac_cv_header_stdint_x=$i],dnl continue,[#include <$i>]) AC_CHECK_TYPE(uint64_t,[and64="(uint64_t too)"],[and64=""],[#include<$i>]) AC_MSG_RESULT(... seen our uintptr_t in $i $and64) break; done if test "$ac_cv_header_stdint_x" = "no-file" ; then for i in stdint.h $inttype_headers ; do unset ac_cv_type_uint32_t unset ac_cv_type_uint64_t AC_CHECK_TYPE(uint32_t,[ac_cv_header_stdint_o=$i],dnl continue,[#include <$i>]) AC_CHECK_TYPE(uint64_t,[and64="(uint64_t too)"],[and64=""],[#include<$i>]) AC_MSG_RESULT(... seen our uint32_t in $i $and64) break; done if test "$ac_cv_header_stdint_o" = "no-file" ; then for i in sys/types.h $inttype_headers ; do unset ac_cv_type_u_int32_t unset ac_cv_type_u_int64_t AC_CHECK_TYPE(u_int32_t,[ac_cv_header_stdint_u=$i],dnl continue,[#include <$i>]) AC_CHECK_TYPE(uint64_t,[and64="(u_int64_t too)"],[and64=""],[#include<$i>]) AC_MSG_RESULT(... seen our u_int32_t in $i $and64) break; done fi fi # ----------------- DONE inttypes.h checks MAYBE C basic types -------- if test "$ac_cv_header_stdint_x" = "no-file" ; then AC_COMPILE_CHECK_SIZEOF(char) AC_COMPILE_CHECK_SIZEOF(short) AC_COMPILE_CHECK_SIZEOF(int) AC_COMPILE_CHECK_SIZEOF(long) AC_COMPILE_CHECK_SIZEOF(void*) ac_cv_header_stdint_test="yes" else ac_cv_header_stdint_test="no" fi # ----------------- DONE inttypes.h checks START header ------------- _ac_stdint_h=AS_TR_CPP(_$ac_stdint_h) AC_MSG_RESULT(creating $ac_stdint_h : $_ac_stdint_h) echo "#ifndef" $_ac_stdint_h >$ac_stdint_h echo "#define" $_ac_stdint_h "1" >>$ac_stdint_h echo "#ifndef" _GENERATED_STDINT_H >>$ac_stdint_h echo "#define" _GENERATED_STDINT_H '"'$PACKAGE $VERSION'"' >>$ac_stdint_h if test "$GCC" = "yes" ; then echo "/* generated using a gnu compiler version" `$CC --version` "*/" \ >>$ac_stdint_h else echo "/* generated using $CC */" >>$ac_stdint_h fi echo "" >>$ac_stdint_h if test "$ac_cv_header_stdint_x" != "no-file" ; then ac_cv_header_stdint="$ac_cv_header_stdint_x" elif test "$ac_cv_header_stdint_o" != "no-file" ; then ac_cv_header_stdint="$ac_cv_header_stdint_o" elif test "$ac_cv_header_stdint_u" != "no-file" ; then ac_cv_header_stdint="$ac_cv_header_stdint_u" else ac_cv_header_stdint="stddef.h" fi # ----------------- See if int_least and int_fast types are present unset ac_cv_type_int_least32_t unset ac_cv_type_int_fast32_t AC_CHECK_TYPE(int_least32_t,,,[#include <$ac_cv_header_stdint>]) AC_CHECK_TYPE(int_fast32_t,,,[#include<$ac_cv_header_stdint>]) if test "$ac_cv_header_stdint" != "stddef.h" ; then if test "$ac_cv_header_stdint" != "stdint.h" ; then AC_MSG_RESULT(..adding include stddef.h) echo "#include " >>$ac_stdint_h fi ; fi AC_MSG_RESULT(..adding include $ac_cv_header_stdint) echo "#include <$ac_cv_header_stdint>" >>$ac_stdint_h echo "" >>$ac_stdint_h # ----------------- DONE header START basic int types ------------- if test "$ac_cv_header_stdint_x" = "no-file" ; then AC_MSG_RESULT(... need to look at C basic types) dnl ac_cv_header_stdint_test="yes" # moved up before creating the file else AC_MSG_RESULT(... seen good stdint.h inttypes) dnl ac_cv_header_stdint_test="no" # moved up before creating the file fi if test "$ac_cv_header_stdint_u" != "no-file" ; then AC_MSG_RESULT(... seen bsd/sysv typedefs) cat >>$ac_stdint_h <>$ac_stdint_h <>$ac_stdint_h <>$ac_stdint_h <>$ac_stdint_h <>$ac_stdint_h <>$ac_stdint_h <>$ac_stdint_h <>$ac_stdint_h <>$ac_stdint_h <>$ac_stdint_h <>$ac_stdint_h < 199901L #ifndef _HAVE_UINT64_T #define _HAVE_UINT64_T typedef long long int64_t; typedef unsigned long long uint64_t; #endif #elif !defined __STRICT_ANSI__ #if defined _MSC_VER || defined __WATCOMC__ || defined __BORLANDC__ #ifndef _HAVE_UINT64_T #define _HAVE_UINT64_T typedef __int64 int64_t; typedef unsigned __int64 uint64_t; #endif #elif defined __GNUC__ || defined __MWERKS__ || defined __ELF__ dnl /* note: all ELF-systems seem to have loff-support which needs 64-bit */ #if !defined _NO_LONGLONG #ifndef _HAVE_UINT64_T #define _HAVE_UINT64_T typedef long long int64_t; typedef unsigned long long uint64_t; #endif #endif #elif defined __alpha || (defined __mips && defined _ABIN32) #if !defined _NO_LONGLONG #ifndef _HAVE_UINT64_T #define _HAVE_UINT64_T typedef long int64_t; typedef unsigned long uint64_t; #endif #endif /* compiler/cpu type ... or just ISO C99 */ #endif #endif EOF # plus a default 64-bit for systems that are likely to be 64-bit ready case "$ac_cv_sizeof_x:$ac_cv_sizeof_voidp:$ac_cv_sizeof_long" in 1:2:8:8) AC_MSG_RESULT(..adding uint64_t default, normal 64-bit system) cat >>$ac_stdint_h <>$ac_stdint_h <>$ac_stdint_h <>$ac_stdint_h <>$ac_stdint_h <>$ac_stdint_h <>$ac_stdint_h <>$ac_stdint_h <>$ac_stdint_h <>$ac_stdint_h <>$ac_stdint_h <>$ac_stdint_h <>$ac_stdint_h < dnl $Id: as-compiler-flag.m4,v 1.1 2005/12/15 23:35:19 ds Exp $ dnl AS_COMPILER_FLAG(CFLAGS, ACTION-IF-ACCEPTED, [ACTION-IF-NOT-ACCEPTED]) dnl Tries to compile with the given CFLAGS. dnl Runs ACTION-IF-ACCEPTED if the compiler can compile with the flags, dnl and ACTION-IF-NOT-ACCEPTED otherwise. AC_DEFUN([AS_COMPILER_FLAG], [ AC_MSG_CHECKING([to see if compiler understands $1]) save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $1" AC_TRY_COMPILE([ ], [], [flag_ok=yes], [flag_ok=no]) CFLAGS="$save_CFLAGS" if test "X$flag_ok" = Xyes ; then m4_ifvaln([$2],[$2]) true else m4_ifvaln([$3],[$3]) true fi AC_MSG_RESULT([$flag_ok]) ]) dnl AS_COMPILER_FLAGS(VAR, FLAGS) dnl Tries to compile with the given CFLAGS. AC_DEFUN([AS_COMPILER_FLAGS], [ list=$2 flags_supported="" flags_unsupported="" AC_MSG_CHECKING([for supported compiler flags]) for each in $list do save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $each" AC_TRY_COMPILE([ ], [], [flag_ok=yes], [flag_ok=no]) CFLAGS="$save_CFLAGS" if test "X$flag_ok" = Xyes ; then flags_supported="$flags_supported $each" else flags_unsupported="$flags_unsupported $each" fi done AC_MSG_RESULT([$flags_supported]) if test "X$flags_unsupported" != X ; then AC_MSG_WARN([unsupported compiler flags: $flags_unsupported]) fi $1="$$1 $flags_supported" ]) mongodb-1.1.5/src/libbson/build/autotools/m4/ax_check_compile_flag.m40000664000175000017500000000625112673034026025411 0ustar jmikolajmikola# =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html # =========================================================================== # # SYNOPSIS # # AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS]) # # DESCRIPTION # # Check whether the given FLAG works with the current language's compiler # or gives an error. (Warnings, however, are ignored) # # ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on # success/failure. # # If EXTRA-FLAGS is defined, it is added to the current language's default # flags (e.g. CFLAGS) when the check is done. The check is thus made with # the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to # force the compiler to issue an error when a bad flag is given. # # NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this # macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG. # # LICENSE # # Copyright (c) 2008 Guido U. Draheim # Copyright (c) 2011 Maarten Bosmans # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation, either version 3 of the License, or (at your # option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 2 AC_DEFUN([AX_CHECK_COMPILE_FLAG], [AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [ ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1" AC_COMPILE_IFELSE([AC_LANG_PROGRAM()], [AS_VAR_SET(CACHEVAR,[yes])], [AS_VAR_SET(CACHEVAR,[no])]) _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags]) AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes], [m4_default([$2], :)], [m4_default([$3], :)]) AS_VAR_POPDEF([CACHEVAR])dnl ])dnl AX_CHECK_COMPILE_FLAGS mongodb-1.1.5/src/libbson/build/autotools/m4/ax_check_link_flag.m40000664000175000017500000000576012673034026024722 0ustar jmikolajmikola# =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_check_link_flag.html # =========================================================================== # # SYNOPSIS # # AX_CHECK_LINK_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS]) # # DESCRIPTION # # Check whether the given FLAG works with the linker or gives an error. # (Warnings, however, are ignored) # # ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on # success/failure. # # If EXTRA-FLAGS is defined, it is added to the linker's default flags # when the check is done. The check is thus made with the flags: "LDFLAGS # EXTRA-FLAGS FLAG". This can for example be used to force the linker to # issue an error when a bad flag is given. # # NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this # macro in sync with AX_CHECK_{PREPROC,COMPILE}_FLAG. # # LICENSE # # Copyright (c) 2008 Guido U. Draheim # Copyright (c) 2011 Maarten Bosmans # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation, either version 3 of the License, or (at your # option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 2 AC_DEFUN([AX_CHECK_LINK_FLAG], [AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_ldflags_$4_$1])dnl AC_CACHE_CHECK([whether the linker accepts $1], CACHEVAR, [ ax_check_save_flags=$LDFLAGS LDFLAGS="$LDFLAGS $4 $1" AC_LINK_IFELSE([AC_LANG_PROGRAM()], [AS_VAR_SET(CACHEVAR,[yes])], [AS_VAR_SET(CACHEVAR,[no])]) LDFLAGS=$ax_check_save_flags]) AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes], [m4_default([$2], :)], [m4_default([$3], :)]) AS_VAR_POPDEF([CACHEVAR])dnl ])dnl AX_CHECK_LINK_FLAGS mongodb-1.1.5/src/libbson/build/autotools/m4/ax_pthread.m40000664000175000017500000003267612673034026023274 0ustar jmikolajmikola# =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_pthread.html # =========================================================================== # # SYNOPSIS # # AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) # # DESCRIPTION # # This macro figures out how to build C programs using POSIX threads. It # sets the PTHREAD_LIBS output variable to the threads library and linker # flags, and the PTHREAD_CFLAGS output variable to any special C compiler # flags that are needed. (The user can also force certain compiler # flags/libs to be tested by setting these environment variables.) # # Also sets PTHREAD_CC to any special C compiler that is needed for # multi-threaded programs (defaults to the value of CC otherwise). (This # is necessary on AIX to use the special cc_r compiler alias.) # # NOTE: You are assumed to not only compile your program with these flags, # but also link it with them as well. e.g. you should link with # $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS # # If you are only building threads programs, you may wish to use these # variables in your default LIBS, CFLAGS, and CC: # # LIBS="$PTHREAD_LIBS $LIBS" # CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # CC="$PTHREAD_CC" # # In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant # has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name # (e.g. PTHREAD_CREATE_UNDETACHED on AIX). # # Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the # PTHREAD_PRIO_INHERIT symbol is defined when compiling with # PTHREAD_CFLAGS. # # ACTION-IF-FOUND is a list of shell commands to run if a threads library # is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it # is not found. If ACTION-IF-FOUND is not specified, the default action # will define HAVE_PTHREAD. # # Please let the authors know if this macro fails on any platform, or if # you have any other suggestions or comments. This macro was based on work # by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help # from M. Frigo), as well as ac_pthread and hb_pthread macros posted by # Alejandro Forero Cuervo to the autoconf macro repository. We are also # grateful for the helpful feedback of numerous users. # # Updated for Autoconf 2.68 by Daniel Richard G. # # LICENSE # # Copyright (c) 2008 Steven G. Johnson # Copyright (c) 2011 Daniel Richard G. # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation, either version 3 of the License, or (at your # option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 21 AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) AC_DEFUN([AX_PTHREAD], [ AC_REQUIRE([AC_CANONICAL_HOST]) AC_LANG_PUSH([C]) ax_pthread_ok=no # We used to check for pthread.h first, but this fails if pthread.h # requires special compiler flags (e.g. on True64 or Sequent). # It gets checked for in the link test anyway. # First of all, check if the user has set any of the PTHREAD_LIBS, # etcetera environment variables, and if threads linking works using # them: if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" save_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) AC_TRY_LINK_FUNC([pthread_join], [ax_pthread_ok=yes]) AC_MSG_RESULT([$ax_pthread_ok]) if test x"$ax_pthread_ok" = xno; then PTHREAD_LIBS="" PTHREAD_CFLAGS="" fi LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" fi # We must check for the threads library under a number of different # names; the ordering is very important because some systems # (e.g. DEC) have both -lpthread and -lpthreads, where one of the # libraries is broken (non-POSIX). # Create a list of thread flags to try. Items starting with a "-" are # C compiler flags, and other items are library names, except for "none" # which indicates that we try without any flags at all, and "pthread-config" # which is a program returning the flags for the Pth emulation library. ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" # The ordering *is* (sometimes) important. Some notes on the # individual items follow: # pthreads: AIX (must check this before -lpthread) # none: in case threads are in libc; should be tried before -Kthread and # other compiler flags to prevent continual compiler warnings # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) # -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) # -pthreads: Solaris/gcc # -mthreads: Mingw32/gcc, Lynx/gcc # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it # doesn't hurt to check since this sometimes defines pthreads too; # also defines -D_REENTRANT) # ... -mt is also the pthreads flag for HP/aCC # pthread: Linux, etcetera # --thread-safe: KAI C++ # pthread-config: use pthread-config program (for GNU Pth library) case ${host_os} in solaris*) # On Solaris (at least, for some versions), libc contains stubbed # (non-functional) versions of the pthreads routines, so link-based # tests will erroneously succeed. (We need to link with -pthreads/-mt/ # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather # a function called by this macro, so we could check for that, but # who knows whether they'll stub that too in a future libc.) So, # we'll just look for -pthreads and -lpthread first: ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags" ;; darwin*) ax_pthread_flags="-pthread $ax_pthread_flags" ;; esac # Clang doesn't consider unrecognized options an error unless we specify # -Werror. We throw in some extra Clang-specific options to ensure that # this doesn't happen for GCC, which also accepts -Werror. AC_MSG_CHECKING([if compiler needs -Werror to reject unknown flags]) save_CFLAGS="$CFLAGS" ax_pthread_extra_flags="-Werror" CFLAGS="$CFLAGS $ax_pthread_extra_flags -Wunknown-warning-option -Wsizeof-array-argument" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([int foo(void);],[foo()])], [AC_MSG_RESULT([yes])], [ax_pthread_extra_flags= AC_MSG_RESULT([no])]) CFLAGS="$save_CFLAGS" if test x"$ax_pthread_ok" = xno; then for flag in $ax_pthread_flags; do case $flag in none) AC_MSG_CHECKING([whether pthreads work without any flags]) ;; -*) AC_MSG_CHECKING([whether pthreads work with $flag]) PTHREAD_CFLAGS="$flag" ;; pthread-config) AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no]) if test x"$ax_pthread_config" = xno; then continue; fi PTHREAD_CFLAGS="`pthread-config --cflags`" PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" ;; *) AC_MSG_CHECKING([for the pthreads library -l$flag]) PTHREAD_LIBS="-l$flag" ;; esac save_LIBS="$LIBS" save_CFLAGS="$CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS $ax_pthread_extra_flags" # Check for various functions. We must include pthread.h, # since some functions may be macros. (On the Sequent, we # need a special flag -Kthread to make this header compile.) # We check for pthread_join because it is in -lpthread on IRIX # while pthread_create is in libc. We check for pthread_attr_init # due to DEC craziness with -lpthreads. We check for # pthread_cleanup_push because it is one of the few pthread # functions on Solaris that doesn't have a non-functional libc stub. # We try pthread_create on general principles. AC_LINK_IFELSE([AC_LANG_PROGRAM([#include static void routine(void *a) { a = 0; } static void *start_routine(void *a) { return a; }], [pthread_t th; pthread_attr_t attr; pthread_create(&th, 0, start_routine, 0); pthread_join(th, 0); pthread_attr_init(&attr); pthread_cleanup_push(routine, 0); pthread_cleanup_pop(0) /* ; */])], [ax_pthread_ok=yes], []) LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" AC_MSG_RESULT([$ax_pthread_ok]) if test "x$ax_pthread_ok" = xyes; then break; fi PTHREAD_LIBS="" PTHREAD_CFLAGS="" done fi # Various other checks: if test "x$ax_pthread_ok" = xyes; then save_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. AC_MSG_CHECKING([for joinable pthread attribute]) attr_name=unknown for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], [int attr = $attr; return attr /* ; */])], [attr_name=$attr; break], []) done AC_MSG_RESULT([$attr_name]) if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], [$attr_name], [Define to necessary symbol if this constant uses a non-standard name on your system.]) fi AC_MSG_CHECKING([if more special flags are required for pthreads]) flag=no case ${host_os} in aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";; osf* | hpux*) flag="-D_REENTRANT";; solaris*) if test "$GCC" = "yes"; then flag="-D_REENTRANT" else # TODO: What about Clang on Solaris? flag="-mt -D_REENTRANT" fi ;; esac AC_MSG_RESULT([$flag]) if test "x$flag" != xno; then PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" fi AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], [ax_cv_PTHREAD_PRIO_INHERIT], [ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[int i = PTHREAD_PRIO_INHERIT;]])], [ax_cv_PTHREAD_PRIO_INHERIT=yes], [ax_cv_PTHREAD_PRIO_INHERIT=no]) ]) AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"], [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.])]) LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" # More AIX lossage: compile with *_r variant if test "x$GCC" != xyes; then case $host_os in aix*) AS_CASE(["x/$CC"], [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], [#handle absolute path differently from PATH based program lookup AS_CASE(["x$CC"], [x/*], [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])], [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])]) ;; esac fi fi test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" AC_SUBST([PTHREAD_LIBS]) AC_SUBST([PTHREAD_CFLAGS]) AC_SUBST([PTHREAD_CC]) # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: if test x"$ax_pthread_ok" = xyes; then ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1]) : else ax_pthread_ok=no $2 fi AC_LANG_POP ])dnl AX_PTHREAD mongodb-1.1.5/src/libbson/build/autotools/m4/libtool.m40000644000175000017500000106011112673034026022601 0ustar jmikolajmikola# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. m4_define([_LT_COPYING], [dnl # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. # # GNU Libtool is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, or # obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ]) # serial 57 LT_INIT # LT_PREREQ(VERSION) # ------------------ # Complain and exit if this libtool version is less that VERSION. m4_defun([LT_PREREQ], [m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, [m4_default([$3], [m4_fatal([Libtool version $1 or higher is required], 63)])], [$2])]) # _LT_CHECK_BUILDDIR # ------------------ # Complain if the absolute build directory name contains unusual characters m4_defun([_LT_CHECK_BUILDDIR], [case `pwd` in *\ * | *\ *) AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; esac ]) # LT_INIT([OPTIONS]) # ------------------ AC_DEFUN([LT_INIT], [AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl AC_BEFORE([$0], [LT_LANG])dnl AC_BEFORE([$0], [LT_OUTPUT])dnl AC_BEFORE([$0], [LTDL_INIT])dnl m4_require([_LT_CHECK_BUILDDIR])dnl dnl Autoconf doesn't catch unexpanded LT_ macros by default: m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 dnl unless we require an AC_DEFUNed macro: AC_REQUIRE([LTOPTIONS_VERSION])dnl AC_REQUIRE([LTSUGAR_VERSION])dnl AC_REQUIRE([LTVERSION_VERSION])dnl AC_REQUIRE([LTOBSOLETE_VERSION])dnl m4_require([_LT_PROG_LTMAIN])dnl _LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) dnl Parse OPTIONS _LT_SET_OPTIONS([$0], [$1]) # This can be used to rebuild libtool when needed LIBTOOL_DEPS="$ltmain" # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' AC_SUBST(LIBTOOL)dnl _LT_SETUP # Only expand once: m4_define([LT_INIT]) ])# LT_INIT # Old names: AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PROG_LIBTOOL], []) dnl AC_DEFUN([AM_PROG_LIBTOOL], []) # _LT_CC_BASENAME(CC) # ------------------- # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. m4_defun([_LT_CC_BASENAME], [for cc_temp in $1""; do case $cc_temp in compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` ]) # _LT_FILEUTILS_DEFAULTS # ---------------------- # It is okay to use these file commands and assume they have been set # sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. m4_defun([_LT_FILEUTILS_DEFAULTS], [: ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} ])# _LT_FILEUTILS_DEFAULTS # _LT_SETUP # --------- m4_defun([_LT_SETUP], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl _LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl dnl _LT_DECL([], [host_alias], [0], [The host system])dnl _LT_DECL([], [host], [0])dnl _LT_DECL([], [host_os], [0])dnl dnl _LT_DECL([], [build_alias], [0], [The build system])dnl _LT_DECL([], [build], [0])dnl _LT_DECL([], [build_os], [0])dnl dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl dnl AC_REQUIRE([AC_PROG_LN_S])dnl test -z "$LN_S" && LN_S="ln -s" _LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl dnl AC_REQUIRE([LT_CMD_MAX_LEN])dnl _LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl _LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl m4_require([_LT_CMD_RELOAD])dnl m4_require([_LT_CHECK_MAGIC_METHOD])dnl m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl m4_require([_LT_CMD_OLD_ARCHIVE])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_WITH_SYSROOT])dnl _LT_CONFIG_LIBTOOL_INIT([ # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi ]) if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi _LT_CHECK_OBJDIR m4_require([_LT_TAG_COMPILER])dnl case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld="$lt_cv_prog_gnu_ld" old_CC="$CC" old_CFLAGS="$CFLAGS" # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o _LT_CC_BASENAME([$compiler]) # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then _LT_PATH_MAGIC fi ;; esac # Use C for the default configuration in the libtool script LT_SUPPORTED_TAG([CC]) _LT_LANG_C_CONFIG _LT_LANG_DEFAULT_CONFIG _LT_CONFIG_COMMANDS ])# _LT_SETUP # _LT_PREPARE_SED_QUOTE_VARS # -------------------------- # Define a few sed substitution that help us do robust quoting. m4_defun([_LT_PREPARE_SED_QUOTE_VARS], [# Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\([["`\\]]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ]) # _LT_PROG_LTMAIN # --------------- # Note that this code is called both from `configure', and `config.status' # now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, # `config.status' has no value for ac_aux_dir unless we are using Automake, # so we pass a copy along to make sure it has a sensible value anyway. m4_defun([_LT_PROG_LTMAIN], [m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl _LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) ltmain="$ac_aux_dir/ltmain.sh" ])# _LT_PROG_LTMAIN ## ------------------------------------- ## ## Accumulate code for creating libtool. ## ## ------------------------------------- ## # So that we can recreate a full libtool script including additional # tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS # in macros and then make a single call at the end using the `libtool' # label. # _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) # ---------------------------------------- # Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL_INIT], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_INIT], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_INIT]) # _LT_CONFIG_LIBTOOL([COMMANDS]) # ------------------------------ # Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) # _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) # ----------------------------------------------------- m4_defun([_LT_CONFIG_SAVE_COMMANDS], [_LT_CONFIG_LIBTOOL([$1]) _LT_CONFIG_LIBTOOL_INIT([$2]) ]) # _LT_FORMAT_COMMENT([COMMENT]) # ----------------------------- # Add leading comment marks to the start of each line, and a trailing # full-stop to the whole comment if one is not present already. m4_define([_LT_FORMAT_COMMENT], [m4_ifval([$1], [ m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) )]) ## ------------------------ ## ## FIXME: Eliminate VARNAME ## ## ------------------------ ## # _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) # ------------------------------------------------------------------- # CONFIGNAME is the name given to the value in the libtool script. # VARNAME is the (base) name used in the configure script. # VALUE may be 0, 1 or 2 for a computed quote escaped value based on # VARNAME. Any other value will be used directly. m4_define([_LT_DECL], [lt_if_append_uniq([lt_decl_varnames], [$2], [, ], [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], [m4_ifval([$1], [$1], [$2])]) lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) m4_ifval([$4], [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) lt_dict_add_subkey([lt_decl_dict], [$2], [tagged?], [m4_ifval([$5], [yes], [no])])]) ]) # _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) # -------------------------------------------------------- m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) # lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_tag_varnames], [_lt_decl_filter([tagged?], [yes], $@)]) # _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) # --------------------------------------------------------- m4_define([_lt_decl_filter], [m4_case([$#], [0], [m4_fatal([$0: too few arguments: $#])], [1], [m4_fatal([$0: too few arguments: $#: $1])], [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], [lt_dict_filter([lt_decl_dict], $@)])[]dnl ]) # lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) # -------------------------------------------------- m4_define([lt_decl_quote_varnames], [_lt_decl_filter([value], [1], $@)]) # lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_dquote_varnames], [_lt_decl_filter([value], [2], $@)]) # lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_varnames_tagged], [m4_assert([$# <= 2])dnl _$0(m4_quote(m4_default([$1], [[, ]])), m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) m4_define([_lt_decl_varnames_tagged], [m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) # lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_all_varnames], [_$0(m4_quote(m4_default([$1], [[, ]])), m4_if([$2], [], m4_quote(lt_decl_varnames), m4_quote(m4_shift($@))))[]dnl ]) m4_define([_lt_decl_all_varnames], [lt_join($@, lt_decl_varnames_tagged([$1], lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl ]) # _LT_CONFIG_STATUS_DECLARE([VARNAME]) # ------------------------------------ # Quote a variable value, and forward it to `config.status' so that its # declaration there will have the same value as in `configure'. VARNAME # must have a single quote delimited value for this to work. m4_define([_LT_CONFIG_STATUS_DECLARE], [$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) # _LT_CONFIG_STATUS_DECLARATIONS # ------------------------------ # We delimit libtool config variables with single quotes, so when # we write them to config.status, we have to be sure to quote all # embedded single quotes properly. In configure, this macro expands # each variable declared with _LT_DECL (and _LT_TAGDECL) into: # # ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], [m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAGS # ---------------- # Output comment and list of tags supported by the script m4_defun([_LT_LIBTOOL_TAGS], [_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl available_tags="_LT_TAGS"dnl ]) # _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) # ----------------------------------- # Extract the dictionary values for VARNAME (optionally with TAG) and # expand to a commented shell variable setting: # # # Some comment about what VAR is for. # visible_name=$lt_internal_name m4_define([_LT_LIBTOOL_DECLARE], [_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [description])))[]dnl m4_pushdef([_libtool_name], m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), [0], [_libtool_name=[$]$1], [1], [_libtool_name=$lt_[]$1], [2], [_libtool_name=$lt_[]$1], [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl ]) # _LT_LIBTOOL_CONFIG_VARS # ----------------------- # Produce commented declarations of non-tagged libtool config variables # suitable for insertion in the LIBTOOL CONFIG section of the `libtool' # script. Tagged libtool config variables (even for the LIBTOOL CONFIG # section) are produced by _LT_LIBTOOL_TAG_VARS. m4_defun([_LT_LIBTOOL_CONFIG_VARS], [m4_foreach([_lt_var], m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAG_VARS(TAG) # ------------------------- m4_define([_LT_LIBTOOL_TAG_VARS], [m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) # _LT_TAGVAR(VARNAME, [TAGNAME]) # ------------------------------ m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) # _LT_CONFIG_COMMANDS # ------------------- # Send accumulated output to $CONFIG_STATUS. Thanks to the lists of # variables for single and double quote escaping we saved from calls # to _LT_DECL, we can put quote escaped variables declarations # into `config.status', and then the shell code to quote escape them in # for loops in `config.status'. Finally, any additional code accumulated # from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. m4_defun([_LT_CONFIG_COMMANDS], [AC_PROVIDE_IFELSE([LT_OUTPUT], dnl If the libtool generation code has been placed in $CONFIG_LT, dnl instead of duplicating it all over again into config.status, dnl then we will have config.status run $CONFIG_LT later, so it dnl needs to know what name is stored there: [AC_CONFIG_COMMANDS([libtool], [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], dnl If the libtool generation code is destined for config.status, dnl expand the accumulated commands and init code now: [AC_CONFIG_COMMANDS([libtool], [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) ])#_LT_CONFIG_COMMANDS # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], [ # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' _LT_CONFIG_STATUS_DECLARATIONS LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$[]1 _LTECHO_EOF' } # Quote evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_quote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_dquote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done _LT_OUTPUT_LIBTOOL_INIT ]) # _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) # ------------------------------------ # Generate a child script FILE with all initialization necessary to # reuse the environment learned by the parent script, and make the # file executable. If COMMENT is supplied, it is inserted after the # `#!' sequence but before initialization text begins. After this # macro, additional text can be appended to FILE to form the body of # the child script. The macro ends with non-zero status if the # file could not be fully written (such as if the disk is full). m4_ifdef([AS_INIT_GENERATED], [m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], [m4_defun([_LT_GENERATED_FILE_INIT], [m4_require([AS_PREPARE])]dnl [m4_pushdef([AS_MESSAGE_LOG_FD])]dnl [lt_write_fail=0 cat >$1 <<_ASEOF || lt_write_fail=1 #! $SHELL # Generated by $as_me. $2 SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$1 <<\_ASEOF || lt_write_fail=1 AS_SHELL_SANITIZE _AS_PREPARE exec AS_MESSAGE_FD>&1 _ASEOF test $lt_write_fail = 0 && chmod +x $1[]dnl m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT # LT_OUTPUT # --------- # This macro allows early generation of the libtool script (before # AC_OUTPUT is called), incase it is used in configure for compilation # tests. AC_DEFUN([LT_OUTPUT], [: ${CONFIG_LT=./config.lt} AC_MSG_NOTICE([creating $CONFIG_LT]) _LT_GENERATED_FILE_INIT(["$CONFIG_LT"], [# Run this file to recreate a libtool stub with the current configuration.]) cat >>"$CONFIG_LT" <<\_LTEOF lt_cl_silent=false exec AS_MESSAGE_LOG_FD>>config.log { echo AS_BOX([Running $as_me.]) } >&AS_MESSAGE_LOG_FD lt_cl_help="\ \`$as_me' creates a local libtool stub from the current configuration, for use in further configure time tests before the real libtool is generated. Usage: $[0] [[OPTIONS]] -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files Report bugs to ." lt_cl_version="\ m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) configured by $[0], generated by m4_PACKAGE_STRING. Copyright (C) 2011 Free Software Foundation, Inc. This config.lt script is free software; the Free Software Foundation gives unlimited permision to copy, distribute and modify it." while test $[#] != 0 do case $[1] in --version | --v* | -V ) echo "$lt_cl_version"; exit 0 ;; --help | --h* | -h ) echo "$lt_cl_help"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --quiet | --q* | --silent | --s* | -q ) lt_cl_silent=: ;; -*) AC_MSG_ERROR([unrecognized option: $[1] Try \`$[0] --help' for more information.]) ;; *) AC_MSG_ERROR([unrecognized argument: $[1] Try \`$[0] --help' for more information.]) ;; esac shift done if $lt_cl_silent; then exec AS_MESSAGE_FD>/dev/null fi _LTEOF cat >>"$CONFIG_LT" <<_LTEOF _LT_OUTPUT_LIBTOOL_COMMANDS_INIT _LTEOF cat >>"$CONFIG_LT" <<\_LTEOF AC_MSG_NOTICE([creating $ofile]) _LT_OUTPUT_LIBTOOL_COMMANDS AS_EXIT(0) _LTEOF chmod +x "$CONFIG_LT" # configure is writing to config.log, but config.lt does its own redirection, # appending to config.log, which fails on DOS, as config.log is still kept # open by configure. Here we exec the FD to /dev/null, effectively closing # config.log, so it can be properly (re)opened and appended to by config.lt. lt_cl_success=: test "$silent" = yes && lt_config_lt_args="$lt_config_lt_args --quiet" exec AS_MESSAGE_LOG_FD>/dev/null $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false exec AS_MESSAGE_LOG_FD>>config.log $lt_cl_success || AS_EXIT(1) ])# LT_OUTPUT # _LT_CONFIG(TAG) # --------------- # If TAG is the built-in tag, create an initial libtool script with a # default configuration from the untagged config vars. Otherwise add code # to config.status for appending the configuration named by TAG from the # matching tagged config vars. m4_defun([_LT_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_CONFIG_SAVE_COMMANDS([ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl m4_if(_LT_TAG, [C], [ # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi cfgfile="${ofile}T" trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # _LT_COPYING _LT_LIBTOOL_TAGS # ### BEGIN LIBTOOL CONFIG _LT_LIBTOOL_CONFIG_VARS _LT_LIBTOOL_TAG_VARS # ### END LIBTOOL CONFIG _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac _LT_PROG_LTMAIN # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) _LT_PROG_REPLACE_SHELLFNS mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ], [cat <<_LT_EOF >> "$ofile" dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded dnl in a comment (ie after a #). # ### BEGIN LIBTOOL TAG CONFIG: $1 _LT_LIBTOOL_TAG_VARS(_LT_TAG) # ### END LIBTOOL TAG CONFIG: $1 _LT_EOF ])dnl /m4_if ], [m4_if([$1], [], [ PACKAGE='$PACKAGE' VERSION='$VERSION' TIMESTAMP='$TIMESTAMP' RM='$RM' ofile='$ofile'], []) ])dnl /_LT_CONFIG_SAVE_COMMANDS ])# _LT_CONFIG # LT_SUPPORTED_TAG(TAG) # --------------------- # Trace this macro to discover what tags are supported by the libtool # --tag option, using: # autoconf --trace 'LT_SUPPORTED_TAG:$1' AC_DEFUN([LT_SUPPORTED_TAG], []) # C support is built-in for now m4_define([_LT_LANG_C_enabled], []) m4_define([_LT_TAGS], []) # LT_LANG(LANG) # ------------- # Enable libtool support for the given language if not already enabled. AC_DEFUN([LT_LANG], [AC_BEFORE([$0], [LT_OUTPUT])dnl m4_case([$1], [C], [_LT_LANG(C)], [C++], [_LT_LANG(CXX)], [Go], [_LT_LANG(GO)], [Java], [_LT_LANG(GCJ)], [Fortran 77], [_LT_LANG(F77)], [Fortran], [_LT_LANG(FC)], [Windows Resource], [_LT_LANG(RC)], [m4_ifdef([_LT_LANG_]$1[_CONFIG], [_LT_LANG($1)], [m4_fatal([$0: unsupported language: "$1"])])])dnl ])# LT_LANG # _LT_LANG(LANGNAME) # ------------------ m4_defun([_LT_LANG], [m4_ifdef([_LT_LANG_]$1[_enabled], [], [LT_SUPPORTED_TAG([$1])dnl m4_append([_LT_TAGS], [$1 ])dnl m4_define([_LT_LANG_]$1[_enabled], [])dnl _LT_LANG_$1_CONFIG($1)])dnl ])# _LT_LANG m4_ifndef([AC_PROG_GO], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_GO. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_GO], [AC_LANG_PUSH(Go)dnl AC_ARG_VAR([GOC], [Go compiler command])dnl AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl _AC_ARG_VAR_LDFLAGS()dnl AC_CHECK_TOOL(GOC, gccgo) if test -z "$GOC"; then if test -n "$ac_tool_prefix"; then AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) fi fi if test -z "$GOC"; then AC_CHECK_PROG(GOC, gccgo, gccgo, false) fi ])#m4_defun ])#m4_ifndef # _LT_LANG_DEFAULT_CONFIG # ----------------------- m4_defun([_LT_LANG_DEFAULT_CONFIG], [AC_PROVIDE_IFELSE([AC_PROG_CXX], [LT_LANG(CXX)], [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) AC_PROVIDE_IFELSE([AC_PROG_F77], [LT_LANG(F77)], [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) AC_PROVIDE_IFELSE([AC_PROG_FC], [LT_LANG(FC)], [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal dnl pulling things in needlessly. AC_PROVIDE_IFELSE([AC_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([LT_PROG_GCJ], [LT_LANG(GCJ)], [m4_ifdef([AC_PROG_GCJ], [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([A][M_PROG_GCJ], [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([LT_PROG_GCJ], [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) AC_PROVIDE_IFELSE([AC_PROG_GO], [LT_LANG(GO)], [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) AC_PROVIDE_IFELSE([LT_PROG_RC], [LT_LANG(RC)], [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) ])# _LT_LANG_DEFAULT_CONFIG # Obsolete macros: AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_CXX], []) dnl AC_DEFUN([AC_LIBTOOL_F77], []) dnl AC_DEFUN([AC_LIBTOOL_FC], []) dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) dnl AC_DEFUN([AC_LIBTOOL_RC], []) # _LT_TAG_COMPILER # ---------------- m4_defun([_LT_TAG_COMPILER], [AC_REQUIRE([AC_PROG_CC])dnl _LT_DECL([LTCC], [CC], [1], [A C compiler])dnl _LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl _LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl _LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC ])# _LT_TAG_COMPILER # _LT_COMPILER_BOILERPLATE # ------------------------ # Check for compiler boilerplate output or warnings with # the simple compiler test code. m4_defun([_LT_COMPILER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ])# _LT_COMPILER_BOILERPLATE # _LT_LINKER_BOILERPLATE # ---------------------- # Check for linker boilerplate output or warnings with # the simple link test code. m4_defun([_LT_LINKER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ])# _LT_LINKER_BOILERPLATE # _LT_REQUIRED_DARWIN_CHECKS # ------------------------- m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ case $host_os in rhapsody* | darwin*) AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) AC_CHECK_TOOL([LIPO], [lipo], [:]) AC_CHECK_TOOL([OTOOL], [otool], [:]) AC_CHECK_TOOL([OTOOL64], [otool64], [:]) _LT_DECL([], [DSYMUTIL], [1], [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) _LT_DECL([], [NMEDIT], [1], [Tool to change global to local symbols on Mac OS X]) _LT_DECL([], [LIPO], [1], [Tool to manipulate fat objects and archives on Mac OS X]) _LT_DECL([], [OTOOL], [1], [ldd/readelf like tool for Mach-O binaries on Mac OS X]) _LT_DECL([], [OTOOL64], [1], [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], [lt_cv_apple_cc_single_mod=no if test -z "${LT_MULTI_MODULE}"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test $_lt_result -eq 0; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -rf libconftest.dylib* rm -f conftest.* fi]) AC_CACHE_CHECK([for -exported_symbols_list linker flag], [lt_cv_ld_exported_symbols_list], [lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [lt_cv_ld_exported_symbols_list=yes], [lt_cv_ld_exported_symbols_list=no]) LDFLAGS="$save_LDFLAGS" ]) AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], [lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then lt_cv_ld_force_load=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM ]) case $host_os in rhapsody* | darwin1.[[012]]) _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; 10.[[012]]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test "$lt_cv_apple_cc_single_mod" = "yes"; then _lt_dar_single_mod='$single_module' fi if test "$lt_cv_ld_exported_symbols_list" = "yes"; then _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' fi if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ]) # _LT_DARWIN_LINKER_FEATURES([TAG]) # --------------------------------- # Checks for linker and compiler features on darwin m4_defun([_LT_DARWIN_LINKER_FEATURES], [ m4_require([_LT_REQUIRED_DARWIN_CHECKS]) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported if test "$lt_cv_ld_force_load" = "yes"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) else _LT_TAGVAR(whole_archive_flag_spec, $1)='' fi _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" m4_if([$1], [CXX], [ if test "$lt_cv_apple_cc_single_mod" != "yes"; then _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" fi ],[]) else _LT_TAGVAR(ld_shlibs, $1)=no fi ]) # _LT_SYS_MODULE_PATH_AIX([TAGNAME]) # ---------------------------------- # Links a minimal program and checks the executable # for the system default hardcoded library path. In most cases, # this is /usr/lib:/lib, but when the MPI compilers are used # the location of the communication and MPI libs are included too. # If we don't find anything, use the default library path according # to the aix ld manual. # Store the results from the different compilers for each TAGNAME. # Allow to override them for all tags through lt_cv_aix_libpath. m4_defun([_LT_SYS_MODULE_PATH_AIX], [m4_require([_LT_DECL_SED])dnl if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ lt_aix_libpath_sed='[ /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }]' _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi],[]) if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib" fi ]) aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) fi ])# _LT_SYS_MODULE_PATH_AIX # _LT_SHELL_INIT(ARG) # ------------------- m4_define([_LT_SHELL_INIT], [m4_divert_text([M4SH-INIT], [$1 ])])# _LT_SHELL_INIT # _LT_PROG_ECHO_BACKSLASH # ----------------------- # Find how we can fake an echo command that does not interpret backslash. # In particular, with Autoconf 2.60 or later we add some code to the start # of the generated configure script which will find a shell with a builtin # printf (which we can use as an echo command). m4_defun([_LT_PROG_ECHO_BACKSLASH], [ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO AC_MSG_CHECKING([how to print strings]) # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $[]1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } case "$ECHO" in printf*) AC_MSG_RESULT([printf]) ;; print*) AC_MSG_RESULT([print -r]) ;; *) AC_MSG_RESULT([cat]) ;; esac m4_ifdef([_AS_DETECT_SUGGESTED], [_AS_DETECT_SUGGESTED([ test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test "X`printf %s $ECHO`" = "X$ECHO" \ || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) _LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) ])# _LT_PROG_ECHO_BACKSLASH # _LT_WITH_SYSROOT # ---------------- AC_DEFUN([_LT_WITH_SYSROOT], [AC_MSG_CHECKING([for sysroot]) AC_ARG_WITH([sysroot], [ --with-sysroot[=DIR] Search for dependent libraries within DIR (or the compiler's sysroot if not specified).], [], [with_sysroot=no]) dnl lt_sysroot will always be passed unquoted. We quote it here dnl in case the user passed a directory name. lt_sysroot= case ${with_sysroot} in #( yes) if test "$GCC" = yes; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) AC_MSG_RESULT([${with_sysroot}]) AC_MSG_ERROR([The sysroot must be an absolute path.]) ;; esac AC_MSG_RESULT([${lt_sysroot:-no}]) _LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl [dependent libraries, and in which our libraries should be installed.])]) # _LT_ENABLE_LOCK # --------------- m4_defun([_LT_ENABLE_LOCK], [AC_ARG_ENABLE([libtool-lock], [AS_HELP_STRING([--disable-libtool-lock], [avoid locking (might break parallel builds)])]) test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE="32" ;; *ELF-64*) HPUX_IA64_MODE="64" ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out which ABI we are using. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then if test "$lt_cv_prog_gnu_ld" = yes; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) case `/usr/bin/file conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; *) LD="${LD-ld} -m elf_i386" ;; esac ;; powerpc64le-*) LD="${LD-ld} -m elf32lppclinux" ;; powerpc64-*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; powerpcle-*) LD="${LD-ld} -m elf64lppc" ;; powerpc-*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -belf" AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, [AC_LANG_PUSH(C) AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) AC_LANG_POP]) if test x"$lt_cv_cc_needs_belf" != x"yes"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS="$SAVE_CFLAGS" fi ;; *-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD="${LD-ld}_sol2" fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks="$enable_libtool_lock" ])# _LT_ENABLE_LOCK # _LT_PROG_AR # ----------- m4_defun([_LT_PROG_AR], [AC_CHECK_TOOLS(AR, [ar], false) : ${AR=ar} : ${AR_FLAGS=cru} _LT_DECL([], [AR], [1], [The archiver]) _LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], [lt_cv_ar_at_file=no AC_COMPILE_IFELSE([AC_LANG_PROGRAM], [echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([lt_ar_try]) if test "$ac_status" -eq 0; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a AC_TRY_EVAL([lt_ar_try]) if test "$ac_status" -ne 0; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a ]) ]) if test "x$lt_cv_ar_at_file" = xno; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi _LT_DECL([], [archiver_list_spec], [1], [How to feed a file listing to the archiver]) ])# _LT_PROG_AR # _LT_CMD_OLD_ARCHIVE # ------------------- m4_defun([_LT_CMD_OLD_ARCHIVE], [_LT_PROG_AR AC_CHECK_TOOL(STRIP, strip, :) test -z "$STRIP" && STRIP=: _LT_DECL([], [STRIP], [1], [A symbol stripping program]) AC_CHECK_TOOL(RANLIB, ranlib, :) test -z "$RANLIB" && RANLIB=: _LT_DECL([], [RANLIB], [1], [Commands used to install an old-style archive]) # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac _LT_DECL([], [old_postinstall_cmds], [2]) _LT_DECL([], [old_postuninstall_cmds], [2]) _LT_TAGDECL([], [old_archive_cmds], [2], [Commands used to build an old-style archive]) _LT_DECL([], [lock_old_archive_extraction], [0], [Whether to use a lock for old archive extraction]) ])# _LT_CMD_OLD_ARCHIVE # _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------------------- # Check whether the given compiler option works AC_DEFUN([_LT_COMPILER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$3" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi fi $RM conftest* ]) if test x"[$]$2" = xyes; then m4_if([$5], , :, [$5]) else m4_if([$6], , :, [$6]) fi ])# _LT_COMPILER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) # _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------- # Check whether the given linker option works AC_DEFUN([_LT_LINKER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $3" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&AS_MESSAGE_LOG_FD $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi else $2=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" ]) if test x"[$]$2" = xyes; then m4_if([$4], , :, [$4]) else m4_if([$5], , :, [$5]) fi ])# _LT_LINKER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) # LT_CMD_MAX_LEN #--------------- AC_DEFUN([LT_CMD_MAX_LEN], [AC_REQUIRE([AC_CANONICAL_HOST])dnl # find the maximum length of command line arguments AC_MSG_CHECKING([the maximum length of command line arguments]) AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl i=0 teststring="ABCD" case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len" && \ test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8 ; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test $i != 17 # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac ]) if test -n $lt_cv_sys_max_cmd_len ; then AC_MSG_RESULT($lt_cv_sys_max_cmd_len) else AC_MSG_RESULT(none) fi max_cmd_len=$lt_cv_sys_max_cmd_len _LT_DECL([], [max_cmd_len], [0], [What is the maximum length of a command?]) ])# LT_CMD_MAX_LEN # Old name: AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) # _LT_HEADER_DLFCN # ---------------- m4_defun([_LT_HEADER_DLFCN], [AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl ])# _LT_HEADER_DLFCN # _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, # ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) # ---------------------------------------------------------------- m4_defun([_LT_TRY_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test "$cross_compiling" = yes; then : [$4] else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF [#line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; }] _LT_EOF if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) $1 ;; x$lt_dlneed_uscore) $2 ;; x$lt_dlunknown|x*) $3 ;; esac else : # compilation failed $3 fi fi rm -fr conftest* ])# _LT_TRY_DLOPEN_SELF # LT_SYS_DLOPEN_SELF # ------------------ AC_DEFUN([LT_SYS_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test "x$enable_dlopen" != xyes; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen="load_add_on" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen="LoadLibrary" lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen="dlopen" lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ lt_cv_dlopen="dyld" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ]) ;; *) AC_CHECK_FUNC([shl_load], [lt_cv_dlopen="shl_load"], [AC_CHECK_LIB([dld], [shl_load], [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], [AC_CHECK_FUNC([dlopen], [lt_cv_dlopen="dlopen"], [AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], [AC_CHECK_LIB([svld], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], [AC_CHECK_LIB([dld], [dld_link], [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) ]) ]) ]) ]) ]) ;; esac if test "x$lt_cv_dlopen" != xno; then enable_dlopen=yes else enable_dlopen=no fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS="$CPPFLAGS" test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS="$LDFLAGS" wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS="$LIBS" LIBS="$lt_cv_dlopen_libs $LIBS" AC_CACHE_CHECK([whether a program can dlopen itself], lt_cv_dlopen_self, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) ]) if test "x$lt_cv_dlopen_self" = xyes; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" AC_CACHE_CHECK([whether a statically linked program can dlopen itself], lt_cv_dlopen_self_static, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) ]) fi CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi _LT_DECL([dlopen_support], [enable_dlopen], [0], [Whether dlopen is supported]) _LT_DECL([dlopen_self], [enable_dlopen_self], [0], [Whether dlopen of programs is supported]) _LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], [Whether dlopen of statically linked programs is supported]) ])# LT_SYS_DLOPEN_SELF # Old name: AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) # _LT_COMPILER_C_O([TAGNAME]) # --------------------------- # Check to see if options -c and -o are simultaneously supported by compiler. # This macro does not hard code the compiler like AC_PROG_CC_C_O. m4_defun([_LT_COMPILER_C_O], [m4_require([_LT_DECL_SED])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes fi fi chmod u+w . 2>&AS_MESSAGE_LOG_FD $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* ]) _LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], [Does compiler simultaneously support -c and -o options?]) ])# _LT_COMPILER_C_O # _LT_COMPILER_FILE_LOCKS([TAGNAME]) # ---------------------------------- # Check to see if we can do hard links to lock some files if needed m4_defun([_LT_COMPILER_FILE_LOCKS], [m4_require([_LT_ENABLE_LOCK])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_COMPILER_C_O([$1]) hard_links="nottested" if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user AC_MSG_CHECKING([if we can lock with hard links]) hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no AC_MSG_RESULT([$hard_links]) if test "$hard_links" = no; then AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) need_locks=warn fi else need_locks=no fi _LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) ])# _LT_COMPILER_FILE_LOCKS # _LT_CHECK_OBJDIR # ---------------- m4_defun([_LT_CHECK_OBJDIR], [AC_CACHE_CHECK([for objdir], [lt_cv_objdir], [rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null]) objdir=$lt_cv_objdir _LT_DECL([], [objdir], [0], [The name of the directory that contains temporary libtool files])dnl m4_pattern_allow([LT_OBJDIR])dnl AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", [Define to the sub-directory in which libtool stores uninstalled libraries.]) ])# _LT_CHECK_OBJDIR # _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) # -------------------------------------- # Check hardcoding attributes. m4_defun([_LT_LINKER_HARDCODE_LIBPATH], [AC_MSG_CHECKING([how to hardcode library paths into programs]) _LT_TAGVAR(hardcode_action, $1)= if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || test -n "$_LT_TAGVAR(runpath_var, $1)" || test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then # We can hardcode non-existent directories. if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then # Linking always hardcodes the temporary library directory. _LT_TAGVAR(hardcode_action, $1)=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. _LT_TAGVAR(hardcode_action, $1)=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. _LT_TAGVAR(hardcode_action, $1)=unsupported fi AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi _LT_TAGDECL([], [hardcode_action], [0], [How to hardcode a shared library path into an executable]) ])# _LT_LINKER_HARDCODE_LIBPATH # _LT_CMD_STRIPLIB # ---------------- m4_defun([_LT_CMD_STRIPLIB], [m4_require([_LT_DECL_EGREP]) striplib= old_striplib= AC_MSG_CHECKING([whether stripping libraries is possible]) if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" AC_MSG_RESULT([yes]) else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP" ; then striplib="$STRIP -x" old_striplib="$STRIP -S" AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi ;; *) AC_MSG_RESULT([no]) ;; esac fi _LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) _LT_DECL([], [striplib], [1]) ])# _LT_CMD_STRIPLIB # _LT_SYS_DYNAMIC_LINKER([TAG]) # ----------------------------- # PORTME Fill in your ld.so characteristics m4_defun([_LT_SYS_DYNAMIC_LINKER], [AC_REQUIRE([AC_CANONICAL_HOST])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_OBJDUMP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl AC_MSG_CHECKING([dynamic linker characteristics]) m4_if([$1], [], [ if test "$GCC" = yes; then case $host_os in darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; *) lt_awk_arg="/^libraries:/" ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;; *) lt_sed_strip_eq="s,=/,/,g" ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary. lt_tmp_lt_search_path_spec= lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path/$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" else test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS=" "; FS="/|\n";} { lt_foo=""; lt_count=0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo="/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[[lt_foo]]++; } if (lt_freq[[lt_foo]] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's,/\([[A-Za-z]]:\),\1,g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi]) library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix[[4-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[[01]] | aix4.[[01]].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[[45]]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' library_names_spec='${libname}.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec="$LIB" if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[[23]].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[[01]]* | freebsdelf3.[[01]]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=yes sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[[3-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], [lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], [lt_cv_shlibpath_overrides_runpath=yes])]) LDFLAGS=$save_LDFLAGS libdir=$save_libdir ]) shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[[89]] | openbsd2.[[89]].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac AC_MSG_RESULT([$dynamic_linker]) test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi _LT_DECL([], [variables_saved_for_relink], [1], [Variables whose values should be saved in libtool wrapper scripts and restored at link time]) _LT_DECL([], [need_lib_prefix], [0], [Do we need the "lib" prefix for modules?]) _LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) _LT_DECL([], [version_type], [0], [Library versioning type]) _LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) _LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) _LT_DECL([], [shlibpath_overrides_runpath], [0], [Is shlibpath searched before the hard-coded library search path?]) _LT_DECL([], [libname_spec], [1], [Format of library name prefix]) _LT_DECL([], [library_names_spec], [1], [[List of archive names. First name is the real one, the rest are links. The last name is the one that the linker finds with -lNAME]]) _LT_DECL([], [soname_spec], [1], [[The coded name of the library, if different from the real name]]) _LT_DECL([], [install_override_mode], [1], [Permission mode override for installation of shared libraries]) _LT_DECL([], [postinstall_cmds], [2], [Command to use after installation of a shared archive]) _LT_DECL([], [postuninstall_cmds], [2], [Command to use after uninstallation of a shared archive]) _LT_DECL([], [finish_cmds], [2], [Commands used to finish a libtool library installation in a directory]) _LT_DECL([], [finish_eval], [1], [[As "finish_cmds", except a single script fragment to be evaled but not shown]]) _LT_DECL([], [hardcode_into_libs], [0], [Whether we should hardcode library paths into libraries]) _LT_DECL([], [sys_lib_search_path_spec], [2], [Compile-time system search path for libraries]) _LT_DECL([], [sys_lib_dlsearch_path_spec], [2], [Run-time system search path for libraries]) ])# _LT_SYS_DYNAMIC_LINKER # _LT_PATH_TOOL_PREFIX(TOOL) # -------------------------- # find a file program which can recognize shared library AC_DEFUN([_LT_PATH_TOOL_PREFIX], [m4_require([_LT_DECL_EGREP])dnl AC_MSG_CHECKING([for $1]) AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, [case $MAGIC_CMD in [[\\/*] | ?:[\\/]*]) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR dnl $ac_dummy forces splitting on constant user-supplied paths. dnl POSIX.2 word splitting is done only on the output of word expansions, dnl not every word. This closes a longstanding sh security hole. ac_dummy="m4_if([$2], , $PATH, [$2])" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$1; then lt_cv_path_MAGIC_CMD="$ac_dir/$1" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac]) MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then AC_MSG_RESULT($MAGIC_CMD) else AC_MSG_RESULT(no) fi _LT_DECL([], [MAGIC_CMD], [0], [Used to examine libraries when file_magic_cmd begins with "file"])dnl ])# _LT_PATH_TOOL_PREFIX # Old name: AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) # _LT_PATH_MAGIC # -------------- # find a file program which can recognize a shared library m4_defun([_LT_PATH_MAGIC], [_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) else MAGIC_CMD=: fi fi ])# _LT_PATH_MAGIC # LT_PATH_LD # ---------- # find the pathname to the GNU or non-GNU linker AC_DEFUN([LT_PATH_LD], [AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PROG_ECHO_BACKSLASH])dnl AC_ARG_WITH([gnu-ld], [AS_HELP_STRING([--with-gnu-ld], [assume the C compiler uses GNU ld @<:@default=no@:>@])], [test "$withval" = no || with_gnu_ld=yes], [with_gnu_ld=no])dnl ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by $CC]) case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [[\\/]]* | ?:[[\\/]]*) re_direlt='/[[^/]][[^/]]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL(lt_cv_path_LD, [if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[[3-9]]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; esac ]) file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown _LT_DECL([], [deplibs_check_method], [1], [Method to check whether dependent libraries are shared objects]) _LT_DECL([], [file_magic_cmd], [1], [Command to use when deplibs_check_method = "file_magic"]) _LT_DECL([], [file_magic_glob], [1], [How to find potential files when deplibs_check_method = "file_magic"]) _LT_DECL([], [want_nocaseglob], [1], [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) ])# _LT_CHECK_MAGIC_METHOD # LT_PATH_NM # ---------- # find the pathname to a BSD- or MS-compatible name lister AC_DEFUN([LT_PATH_NM], [AC_REQUIRE([AC_PROG_CC])dnl AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, [if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM="$NM" else lt_nm_to_check="${ac_tool_prefix}nm" if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. tmp_nm="$ac_dir/$lt_tmp_nm" if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then # Check to see if the nm accepts a BSD-compat flag. # Adding the `sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS="$lt_save_ifs" done : ${lt_cv_path_NM=no} fi]) if test "$lt_cv_path_NM" != "no"; then NM="$lt_cv_path_NM" else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols" ;; *) DUMPBIN=: ;; esac fi AC_SUBST([DUMPBIN]) if test "$DUMPBIN" != ":"; then NM="$DUMPBIN" fi fi test -z "$NM" && NM=nm AC_SUBST([NM]) _LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], [lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) cat conftest.out >&AS_MESSAGE_LOG_FD if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest*]) ])# LT_PATH_NM # Old names: AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_PROG_NM], []) dnl AC_DEFUN([AC_PROG_NM], []) # _LT_CHECK_SHAREDLIB_FROM_LINKLIB # -------------------------------- # how to determine the name of the shared library # associated with a specific link library. # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], [m4_require([_LT_DECL_EGREP]) m4_require([_LT_DECL_OBJDUMP]) m4_require([_LT_DECL_DLLTOOL]) AC_CACHE_CHECK([how to associate runtime and link libraries], lt_cv_sharedlib_from_linklib_cmd, [lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh # decide which to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd="$ECHO" ;; esac ]) sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO _LT_DECL([], [sharedlib_from_linklib_cmd], [1], [Command to associate shared and link libraries]) ])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB # _LT_PATH_MANIFEST_TOOL # ---------------------- # locate the manifest tool m4_defun([_LT_PATH_MANIFEST_TOOL], [AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], [lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&AS_MESSAGE_LOG_FD if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest*]) if test "x$lt_cv_path_mainfest_tool" != xyes; then MANIFEST_TOOL=: fi _LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl ])# _LT_PATH_MANIFEST_TOOL # LT_LIB_M # -------- # check for math library AC_DEFUN([LT_LIB_M], [AC_REQUIRE([AC_CANONICAL_HOST])dnl LIBM= case $host in *-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) # These system don't have libm, or don't need it ;; *-ncr-sysv4.3*) AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") ;; *) AC_CHECK_LIB(m, cos, LIBM="-lm") ;; esac AC_SUBST([LIBM]) ])# LT_LIB_M # Old name: AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_CHECK_LIBM], []) # _LT_COMPILER_NO_RTTI([TAGNAME]) # ------------------------------- m4_defun([_LT_COMPILER_NO_RTTI], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= if test "$GCC" = yes; then case $cc_basename in nvcc*) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; *) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; esac _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], lt_cv_prog_compiler_rtti_exceptions, [-fno-rtti -fno-exceptions], [], [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) fi _LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], [Compiler flag to turn off builtin functions]) ])# _LT_COMPILER_NO_RTTI # _LT_CMD_GLOBAL_SYMBOLS # ---------------------- m4_defun([_LT_CMD_GLOBAL_SYMBOLS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([LT_PATH_NM])dnl AC_REQUIRE([LT_PATH_LD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_TAG_COMPILER])dnl # Check for command to grab the raw symbol name followed by C symbol from nm. AC_MSG_CHECKING([command to parse $NM output from $compiler object]) AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [ # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[[BCDEGRST]]' # Regexp to match symbols that can be accessed directly from C. sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[[BCDT]]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[[ABCDGISTW]]' ;; hpux*) if test "$host_cpu" = ia64; then symcode='[[ABCDEGRST]]' fi ;; irix* | nonstopux*) symcode='[[BCDEGRST]]' ;; osf*) symcode='[[BCDEGQRST]]' ;; solaris*) symcode='[[BDRT]]' ;; sco3.2v5*) symcode='[[DT]]' ;; sysv4.2uw2*) symcode='[[DT]]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[[ABDT]]' ;; sysv4) symcode='[[DFNSTU]]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[[ABCDGIRSTW]]' ;; esac # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function # and D for any global variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ " {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ " s[1]~/^[@?]/{print s[1], s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx]" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. nlist=conftest.nm if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT@&t@_DLSYM_CONST #elif defined(__osf__) /* This system does not cope well with relocations in const data. */ # define LT@&t@_DLSYM_CONST #else # define LT@&t@_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT@&t@_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[[]] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD fi else echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test "$pipe_works" = yes; then break else lt_cv_sys_global_symbol_pipe= fi done ]) if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then AC_MSG_RESULT(failed) else AC_MSG_RESULT(ok) fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then nm_file_list_spec='@' fi _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], [Take the output of nm and produce a listing of raw symbols and C names]) _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], [Transform the output of nm in a proper C declaration]) _LT_DECL([global_symbol_to_c_name_address], [lt_cv_sys_global_symbol_to_c_name_address], [1], [Transform the output of nm in a C name address pair]) _LT_DECL([global_symbol_to_c_name_address_lib_prefix], [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], [Transform the output of nm in a C name address pair when lib prefix is needed]) _LT_DECL([], [nm_file_list_spec], [1], [Specify filename containing input files for $NM]) ]) # _LT_CMD_GLOBAL_SYMBOLS # _LT_COMPILER_PIC([TAGNAME]) # --------------------------- m4_defun([_LT_COMPILER_PIC], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_wl, $1)= _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)= m4_if([$1], [CXX], [ # C++ specific cases for pic, static, wl, etc. if test "$GXX" = yes; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac else case $host_os in aix[[4-9]]*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; dgux*) case $cc_basename in ec++*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; ghcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; freebsd* | dragonfly*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' if test "$host_cpu" != ia64; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' fi ;; aCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # KAI C++ Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64 which still supported -KPIC. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL 8.0, 9.0 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' ;; *) ;; esac ;; netbsd* | netbsdelf*-gnu) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; cxx*) # Digital/Compaq C++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; lcc*) # Lucid _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ], [ if test "$GCC" = yes; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; hpux9* | hpux10* | hpux11*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC (with -KPIC) is the default. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in # old Intel for x86_64 which still supported -KPIC. ecc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # Lahey Fortran 8.1. lf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' ;; nagfor*) # NAG Fortran compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; ccc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All Alpha code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='' ;; *Sun\ F* | *Sun*Fortran*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ;; *Intel*\ [[CF]]*Compiler*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; *Portland\ Group*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; esac ;; newsos6) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All OSF/1 code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; rdos*) _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; solaris*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; *) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; esac ;; sunos4*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; unicos*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; uts4*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ]) case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" ;; esac AC_CACHE_CHECK([for $compiler option to produce PIC], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) _LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) # # Check to make sure the PIC flag actually works. # if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in "" | " "*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; esac], [_LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) fi _LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], [Additional compiler flags for building library objects]) _LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], [How to pass a linker flag through the compiler]) # # Check to make sure the static flag actually works. # wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" _LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), $lt_tmp_static_flag, [], [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) _LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], [Compiler flag to prevent dynamic linking]) ])# _LT_COMPILER_PIC # _LT_LINKER_SHLIBS([TAGNAME]) # ---------------------------- # See if the linker supports building shared libraries. m4_defun([_LT_LINKER_SHLIBS], [AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) m4_if([$1], [CXX], [ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] case $host_os in aix[[4-9]]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm # Also, AIX nm treats weak defined symbols like other global defined # symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi ;; pw32*) _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" ;; cygwin* | mingw* | cegcc*) case $cc_basename in cl*) _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] ;; esac ;; linux* | k*bsd*-gnu | gnu*) _LT_TAGVAR(link_all_deplibs, $1)=no ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac ], [ runpath_var= _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_cmds, $1)= _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(old_archive_from_new_cmds, $1)= _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= _LT_TAGVAR(thread_safe_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list _LT_TAGVAR(include_expsyms, $1)= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. dnl Note also adjust exclude_expsyms for C++ above. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; linux* | k*bsd*-gnu | gnu*) _LT_TAGVAR(link_all_deplibs, $1)=no ;; esac _LT_TAGVAR(ld_shlibs, $1)=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test "$with_gnu_ld" = yes; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test "$lt_use_gnu_ld_interface" = yes; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi supports_anon_versioning=no case `$LD -v 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[[3-9]]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test "$host_os" = linux-dietlibc; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test "$tmp_diet" = no then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 _LT_TAGVAR(whole_archive_flag_spec, $1)= tmp_sharedflag='--shared' ;; xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi case $cc_basename in xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; sunos4*) _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then runpath_var= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. _LT_TAGVAR(hardcode_minus_L, $1)=yes if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. _LT_TAGVAR(hardcode_direct, $1)=unsupported fi ;; aix[[4-9]]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm # Also, AIX nm treats weak defined symbols like other global # defined symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' if test "$GCC" = yes; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi _LT_TAGVAR(link_all_deplibs, $1)=no else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. _LT_TAGVAR(always_export_symbols, $1)=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; bsdi[[45]]*) _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl*) # Native MSVC _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' # FIXME: Should let the user specify the lib program. _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; hpux9*) if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; hpux10*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test "$with_gnu_ld" = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes fi ;; hpux11*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) m4_if($1, [], [ # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) _LT_LINKER_OPTION([if $CC understands -b], _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) ;; esac fi if test "$with_gnu_ld" = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], [lt_cv_irix_exported_symbol], [save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" AC_LINK_IFELSE( [AC_LANG_SOURCE( [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], [C++], [[int foo (void) { return 0; }]], [Fortran 77], [[ subroutine foo end]], [Fortran], [[ subroutine foo end]])])], [lt_cv_irix_exported_symbol=yes], [lt_cv_irix_exported_symbol=no]) LDFLAGS="$save_LDFLAGS"]) if test "$lt_cv_irix_exported_symbol" = yes; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' fi else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes _LT_TAGVAR(link_all_deplibs, $1)=yes ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; newsos6) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *nto* | *qnx*) ;; openbsd*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' else case $host_os in openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' ;; esac fi else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; solaris*) _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' if test "$GCC" = yes; then wlarc='${wl}' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='${wl}' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. GCC discards it without `$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test "$GCC" = yes; then _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' else _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' fi ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes ;; sunos4*) if test "x$host_vendor" = xsequent; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4) case $host_vendor in sni) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' _LT_TAGVAR(hardcode_direct, $1)=no ;; motorola) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4.3*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes _LT_TAGVAR(ld_shlibs, $1)=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(ld_shlibs, $1)=no ;; esac if test x$host_vendor = xsni; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' ;; esac fi fi ]) AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no _LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld _LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl _LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl _LT_DECL([], [extract_expsyms_cmds], [2], [The commands to extract the exported symbol list from a shared archive]) # # Do we need to explicitly link libc? # case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in x|xyes) # Assume -lc should be added _LT_TAGVAR(archive_cmds_need_lc, $1)=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $_LT_TAGVAR(archive_cmds, $1) in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. AC_CACHE_CHECK([whether -lc should be explicitly linked in], [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), [$RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if AC_TRY_EVAL(ac_compile) 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) _LT_TAGVAR(allow_undefined_flag, $1)= if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) then lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no else lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes fi _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* ]) _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) ;; esac fi ;; esac _LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], [Whether or not to add -lc for building shared libraries]) _LT_TAGDECL([allow_libtool_libs_with_static_runtimes], [enable_shared_with_static_runtimes], [0], [Whether or not to disallow shared libs when runtime libs are static]) _LT_TAGDECL([], [export_dynamic_flag_spec], [1], [Compiler flag to allow reflexive dlopens]) _LT_TAGDECL([], [whole_archive_flag_spec], [1], [Compiler flag to generate shared objects directly from archives]) _LT_TAGDECL([], [compiler_needs_object], [1], [Whether the compiler copes with passing no objects directly]) _LT_TAGDECL([], [old_archive_from_new_cmds], [2], [Create an old-style archive from a shared archive]) _LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], [Create a temporary old-style archive to link instead of a shared archive]) _LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) _LT_TAGDECL([], [archive_expsym_cmds], [2]) _LT_TAGDECL([], [module_cmds], [2], [Commands used to build a loadable module if different from building a shared archive.]) _LT_TAGDECL([], [module_expsym_cmds], [2]) _LT_TAGDECL([], [with_gnu_ld], [1], [Whether we are building with GNU ld or not]) _LT_TAGDECL([], [allow_undefined_flag], [1], [Flag that allows shared libraries with undefined symbols to be built]) _LT_TAGDECL([], [no_undefined_flag], [1], [Flag that enforces no undefined symbols]) _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], [Flag to hardcode $libdir into a binary during linking. This must work even if $libdir does not exist]) _LT_TAGDECL([], [hardcode_libdir_separator], [1], [Whether we need a single "-rpath" flag with a separated argument]) _LT_TAGDECL([], [hardcode_direct], [0], [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_direct_absolute], [0], [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the resulting binary and the resulting library dependency is "absolute", i.e impossible to change by setting ${shlibpath_var} if the library is relocated]) _LT_TAGDECL([], [hardcode_minus_L], [0], [Set to "yes" if using the -LDIR flag during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_shlibpath_var], [0], [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_automatic], [0], [Set to "yes" if building a shared library automatically hardcodes DIR into the library and all subsequent libraries and executables linked against it]) _LT_TAGDECL([], [inherit_rpath], [0], [Set to yes if linker adds runtime paths of dependent libraries to runtime path list]) _LT_TAGDECL([], [link_all_deplibs], [0], [Whether libtool must link a program against all its dependency libraries]) _LT_TAGDECL([], [always_export_symbols], [0], [Set to "yes" if exported symbols are required]) _LT_TAGDECL([], [export_symbols_cmds], [2], [The commands to list exported symbols]) _LT_TAGDECL([], [exclude_expsyms], [1], [Symbols that should not be listed in the preloaded symbols]) _LT_TAGDECL([], [include_expsyms], [1], [Symbols that must always be exported]) _LT_TAGDECL([], [prelink_cmds], [2], [Commands necessary for linking programs (against libraries) with templates]) _LT_TAGDECL([], [postlink_cmds], [2], [Commands necessary for finishing linking programs]) _LT_TAGDECL([], [file_list_spec], [1], [Specify filename containing input files]) dnl FIXME: Not yet implemented dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], dnl [Compiler flag to generate thread safe objects]) ])# _LT_LINKER_SHLIBS # _LT_LANG_C_CONFIG([TAG]) # ------------------------ # Ensure that the configuration variables for a C compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to `libtool'. m4_defun([_LT_LANG_C_CONFIG], [m4_require([_LT_DECL_EGREP])dnl lt_save_CC="$CC" AC_LANG_PUSH(C) # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' _LT_TAG_COMPILER # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) LT_SYS_DLOPEN_SELF _LT_CMD_STRIPLIB # Report which library types will actually be built AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_CONFIG($1) fi AC_LANG_POP CC="$lt_save_CC" ])# _LT_LANG_C_CONFIG # _LT_LANG_CXX_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a C++ compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to `libtool'. m4_defun([_LT_LANG_CXX_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl if test -n "$CXX" && ( test "X$CXX" != "Xno" && ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || (test "X$CXX" != "Xg++"))) ; then AC_PROG_CXXCPP else _lt_caught_CXX_error=yes fi AC_LANG_PUSH(C++) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_caught_CXX_error" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} CFLAGS=$CXXFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test "$GXX" = yes; then _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' else _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= fi if test "$GXX" = yes; then # Set up default GNU C++ configuration LT_PATH_LD # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test "$with_gnu_ld" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='${wl}' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) _LT_TAGVAR(ld_shlibs, $1)=yes case $host_os in aix3*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aix[[4-9]]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' if test "$GXX" = yes; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. _LT_TAGVAR(always_export_symbols, $1)=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an empty # executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared # libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in ,cl* | no,cl*) # Native MSVC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ func_to_tool_file "$lt_outputfile"~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; freebsd2.*) # C++ shared libraries reported to be fairly broken before # switch to ELF _LT_TAGVAR(ld_shlibs, $1)=no ;; freebsd-elf*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; freebsd* | dragonfly*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions _LT_TAGVAR(ld_shlibs, $1)=yes ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; hpux9*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; hpux10*|hpux11*) if test $with_gnu_ld = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) ;; *) _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes; then if test $with_gnu_ld = no; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test "$GXX" = yes; then if test "$with_gnu_ld" = no; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' fi fi _LT_TAGVAR(link_all_deplibs, $1)=yes ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ $RANLIB $oldlib' _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ;; cxx*) # Compaq C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; m88k*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) _LT_TAGVAR(ld_shlibs, $1)=yes ;; openbsd2*) # C++ shared libraries are fairly broken _LT_TAGVAR(ld_shlibs, $1)=no ;; openbsd*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; cxx*) case $host in osf3*) _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' ;; *) _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ $RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ;; esac _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' case $host in osf3*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # g++ 2.7 appears to require `-G' NOT `-shared' on this # platform. _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ '"$_LT_TAGVAR(old_archive_cmds, $1)" _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ '"$_LT_TAGVAR(reload_cmds, $1)" ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no _LT_TAGVAR(GCC, $1)="$GXX" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test "$_lt_caught_CXX_error" != yes AC_LANG_POP ])# _LT_LANG_CXX_CONFIG # _LT_FUNC_STRIPNAME_CNF # ---------------------- # func_stripname_cnf prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # # This function is identical to the (non-XSI) version of func_stripname, # except this one can be used by m4 code that may be executed by configure, # rather than the libtool script. m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl AC_REQUIRE([_LT_DECL_SED]) AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) func_stripname_cnf () { case ${2} in .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; esac } # func_stripname_cnf ])# _LT_FUNC_STRIPNAME_CNF # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) # --------------------------------- # Figure out "hidden" library dependencies from verbose # compiler output when linking a shared library. # Parse the compiler output and extract the necessary # objects, libraries and library flags. m4_defun([_LT_SYS_HIDDEN_LIBDEPS], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl # Dependencies to place before and after the object being linked: _LT_TAGVAR(predep_objects, $1)= _LT_TAGVAR(postdep_objects, $1)= _LT_TAGVAR(predeps, $1)= _LT_TAGVAR(postdeps, $1)= _LT_TAGVAR(compiler_lib_search_path, $1)= dnl we can't use the lt_simple_compile_test_code here, dnl because it contains code intended for an executable, dnl not a library. It's possible we should let each dnl tag define a new lt_????_link_test_code variable, dnl but it's only used here... m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF int a; void foo (void) { a = 0; } _LT_EOF ], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF ], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer*4 a a=0 return end _LT_EOF ], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer a a=0 return end _LT_EOF ], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF public class foo { private int a; public void bar (void) { a = 0; } }; _LT_EOF ], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF package foo func foo() { } _LT_EOF ]) _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; *\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; esac dnl Parse the compiler output and extract the necessary dnl objects, libraries and library flags. if AC_TRY_EVAL(ac_compile); then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case ${prev}${p} in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test $p = "-L" || test $p = "-R"; then prev=$p continue fi # Expand the sysroot to ease extracting the directories later. if test -z "$prev"; then case $p in -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; esac fi case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac if test "$pre_test_object_deps_done" = no; then case ${prev} in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" else _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$_LT_TAGVAR(postdeps, $1)"; then _LT_TAGVAR(postdeps, $1)="${prev}${p}" else _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" fi fi prev= ;; *.lto.$objext) ;; # Ignore GCC LTO objects *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test "$pre_test_object_deps_done" = no; then if test -z "$_LT_TAGVAR(predep_objects, $1)"; then _LT_TAGVAR(predep_objects, $1)="$p" else _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" fi else if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then _LT_TAGVAR(postdep_objects, $1)="$p" else _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling $1 test program" fi $RM -f confest.$objext CFLAGS=$_lt_libdeps_save_CFLAGS # PORTME: override above test on systems where it is broken m4_if([$1], [CXX], [case $host_os in interix[[3-9]]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. _LT_TAGVAR(predep_objects,$1)= _LT_TAGVAR(postdep_objects,$1)= _LT_TAGVAR(postdeps,$1)= ;; linux*) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac if test "$solaris_use_stlport4" != yes; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac # Adding this requires a known-good setup of shared libraries for # Sun compiler versions before 5.6, else PIC objects from an old # archive will be linked into the output, leading to subtle bugs. if test "$solaris_use_stlport4" != yes; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; esac ;; esac ]) case " $_LT_TAGVAR(postdeps, $1) " in *" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; esac _LT_TAGVAR(compiler_lib_search_dirs, $1)= if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` fi _LT_TAGDECL([], [compiler_lib_search_dirs], [1], [The directories searched by this compiler when creating a shared library]) _LT_TAGDECL([], [predep_objects], [1], [Dependencies to place before and after the objects being linked to create a shared library]) _LT_TAGDECL([], [postdep_objects], [1]) _LT_TAGDECL([], [predeps], [1]) _LT_TAGDECL([], [postdeps], [1]) _LT_TAGDECL([], [compiler_lib_search_path], [1], [The library search path used internally by the compiler when linking a shared library]) ])# _LT_SYS_HIDDEN_LIBDEPS # _LT_LANG_F77_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a Fortran 77 compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_F77_CONFIG], [AC_LANG_PUSH(Fortran 77) if test -z "$F77" || test "X$F77" = "Xno"; then _lt_disable_F77=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for f77 test sources. ac_ext=f # Object file extension for compiled f77 test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the F77 compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_disable_F77" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${F77-"f77"} CFLAGS=$FFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) GCC=$G77 if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)="$G77" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC="$lt_save_CC" CFLAGS="$lt_save_CFLAGS" fi # test "$_lt_disable_F77" != yes AC_LANG_POP ])# _LT_LANG_F77_CONFIG # _LT_LANG_FC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for a Fortran compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_FC_CONFIG], [AC_LANG_PUSH(Fortran) if test -z "$FC" || test "X$FC" = "Xno"; then _lt_disable_FC=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for fc test sources. ac_ext=${ac_fc_srcext-f} # Object file extension for compiled fc test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the FC compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_disable_FC" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${FC-"f95"} CFLAGS=$FCFLAGS compiler=$CC GCC=$ac_cv_fc_compiler_gnu _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS fi # test "$_lt_disable_FC" != yes AC_LANG_POP ])# _LT_LANG_FC_CONFIG # _LT_LANG_GCJ_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Java Compiler compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_GCJ_CONFIG], [AC_REQUIRE([LT_PROG_GCJ])dnl AC_LANG_SAVE # Source file extension for Java test sources. ac_ext=java # Object file extension for compiled Java test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="class foo {}" # Code to be used in simple link tests lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GCJ-"gcj"} CFLAGS=$GCJFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)="$LD" _LT_CC_BASENAME([$compiler]) # GCJ did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GCJ_CONFIG # _LT_LANG_GO_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Go compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_GO_CONFIG], [AC_REQUIRE([LT_PROG_GO])dnl AC_LANG_SAVE # Source file extension for Go test sources. ac_ext=go # Object file extension for compiled Go test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="package main; func main() { }" # Code to be used in simple link tests lt_simple_link_test_code='package main; func main() { }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GOC-"gccgo"} CFLAGS=$GOFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)="$LD" _LT_CC_BASENAME([$compiler]) # Go did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GO_CONFIG # _LT_LANG_RC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for the Windows resource compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_RC_CONFIG], [AC_REQUIRE([LT_PROG_RC])dnl AC_LANG_SAVE # Source file extension for RC test sources. ac_ext=rc # Object file extension for compiled RC test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' # Code to be used in simple link tests lt_simple_link_test_code="$lt_simple_compile_test_code" # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC= CC=${RC-"windres"} CFLAGS= compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes if test -n "$compiler"; then : _LT_CONFIG($1) fi GCC=$lt_save_GCC AC_LANG_RESTORE CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_RC_CONFIG # LT_PROG_GCJ # ----------- AC_DEFUN([LT_PROG_GCJ], [m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], [AC_CHECK_TOOL(GCJ, gcj,) test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" AC_SUBST(GCJFLAGS)])])[]dnl ]) # Old name: AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_GCJ], []) # LT_PROG_GO # ---------- AC_DEFUN([LT_PROG_GO], [AC_CHECK_TOOL(GOC, gccgo,) ]) # LT_PROG_RC # ---------- AC_DEFUN([LT_PROG_RC], [AC_CHECK_TOOL(RC, windres,) ]) # Old name: AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_RC], []) # _LT_DECL_EGREP # -------------- # If we don't have a new enough Autoconf to choose the best grep # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_EGREP], [AC_REQUIRE([AC_PROG_EGREP])dnl AC_REQUIRE([AC_PROG_FGREP])dnl test -z "$GREP" && GREP=grep _LT_DECL([], [GREP], [1], [A grep program that handles long lines]) _LT_DECL([], [EGREP], [1], [An ERE matcher]) _LT_DECL([], [FGREP], [1], [A literal string matcher]) dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too AC_SUBST([GREP]) ]) # _LT_DECL_OBJDUMP # -------------- # If we don't have a new enough Autoconf to choose the best objdump # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_OBJDUMP], [AC_CHECK_TOOL(OBJDUMP, objdump, false) test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) AC_SUBST([OBJDUMP]) ]) # _LT_DECL_DLLTOOL # ---------------- # Ensure DLLTOOL variable is set. m4_defun([_LT_DECL_DLLTOOL], [AC_CHECK_TOOL(DLLTOOL, dlltool, false) test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program]) AC_SUBST([DLLTOOL]) ]) # _LT_DECL_SED # ------------ # Check for a fully-functional sed program, that truncates # as few characters as possible. Prefer GNU sed if found. m4_defun([_LT_DECL_SED], [AC_PROG_SED test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" _LT_DECL([], [SED], [1], [A sed program that does not truncate output]) _LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], [Sed that helps us avoid accidentally triggering echo(1) options like -n]) ])# _LT_DECL_SED m4_ifndef([AC_PROG_SED], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_SED. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_SED], [AC_MSG_CHECKING([for a sed that does not truncate output]) AC_CACHE_VAL(lt_cv_path_SED, [# Loop through the user's path and test for sed and gsed. # Then use that list of sed's as ones to test for truncation. as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for lt_ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" fi done done done IFS=$as_save_IFS lt_ac_max=0 lt_ac_count=0 # Add /usr/xpg4/bin/sed as it is typically found on Solaris # along with /bin/sed that truncates output. for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do test ! -f $lt_ac_sed && continue cat /dev/null > conftest.in lt_ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >conftest.in # Check for GNU sed and select it if it is found. if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then lt_cv_path_SED=$lt_ac_sed break fi while true; do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo >>conftest.nl $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break cmp -s conftest.out conftest.nl || break # 10000 chars as input seems more than enough test $lt_ac_count -gt 10 && break lt_ac_count=`expr $lt_ac_count + 1` if test $lt_ac_count -gt $lt_ac_max; then lt_ac_max=$lt_ac_count lt_cv_path_SED=$lt_ac_sed fi done done ]) SED=$lt_cv_path_SED AC_SUBST([SED]) AC_MSG_RESULT([$SED]) ])#AC_PROG_SED ])#m4_ifndef # Old name: AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_SED], []) # _LT_CHECK_SHELL_FEATURES # ------------------------ # Find out whether the shell is Bourne or XSI compatible, # or has some other useful features. m4_defun([_LT_CHECK_SHELL_FEATURES], [AC_MSG_CHECKING([whether the shell understands some XSI constructs]) # Try some XSI features xsi_shell=no ( _lt_dummy="a/b/c" test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ = c,a/b,b/c, \ && eval 'test $(( 1 + 1 )) -eq 2 \ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ && xsi_shell=yes AC_MSG_RESULT([$xsi_shell]) _LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) AC_MSG_CHECKING([whether the shell understands "+="]) lt_shell_append=no ( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ >/dev/null 2>&1 \ && lt_shell_append=yes AC_MSG_RESULT([$lt_shell_append]) _LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi _LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac _LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl ])# _LT_CHECK_SHELL_FEATURES # _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY) # ------------------------------------------------------ # In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and # '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY. m4_defun([_LT_PROG_FUNCTION_REPLACE], [dnl { sed -e '/^$1 ()$/,/^} # $1 /c\ $1 ()\ {\ m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1]) } # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: ]) # _LT_PROG_REPLACE_SHELLFNS # ------------------------- # Replace existing portable implementations of several shell functions with # equivalent extended shell implementations where those features are available.. m4_defun([_LT_PROG_REPLACE_SHELLFNS], [if test x"$xsi_shell" = xyes; then _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac]) _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl func_basename_result="${1##*/}"]) _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac func_basename_result="${1##*/}"]) _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are # positional parameters, so assign one to ordinary parameter first. func_stripname_result=${3} func_stripname_result=${func_stripname_result#"${1}"} func_stripname_result=${func_stripname_result%"${2}"}]) _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl func_split_long_opt_name=${1%%=*} func_split_long_opt_arg=${1#*=}]) _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl func_split_short_opt_arg=${1#??} func_split_short_opt_name=${1%"$func_split_short_opt_arg"}]) _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl case ${1} in *.lo) func_lo2o_result=${1%.lo}.${objext} ;; *) func_lo2o_result=${1} ;; esac]) _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo]) _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))]) _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}]) fi if test x"$lt_shell_append" = xyes; then _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"]) _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl func_quote_for_eval "${2}" dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \ eval "${1}+=\\\\ \\$func_quote_for_eval_result"]) # Save a `func_append' function call where possible by direct use of '+=' sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: else # Save a `func_append' function call even when '+=' is not available sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: fi if test x"$_lt_function_replace_fail" = x":"; then AC_MSG_WARN([Unable to substitute extended shell functions in $ofile]) fi ]) # _LT_PATH_CONVERSION_FUNCTIONS # ----------------------------- # Determine which file name conversion functions should be used by # func_to_host_file (and, implicitly, by func_to_host_path). These are needed # for certain cross-compile configurations and native mingw. m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_MSG_CHECKING([how to convert $build file names to $host format]) AC_CACHE_VAL(lt_cv_to_host_file_cmd, [case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac ]) to_host_file_cmd=$lt_cv_to_host_file_cmd AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) _LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], [0], [convert $build file names to $host format])dnl AC_MSG_CHECKING([how to convert $build file names to toolchain format]) AC_CACHE_VAL(lt_cv_to_tool_file_cmd, [#assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac ]) to_tool_file_cmd=$lt_cv_to_tool_file_cmd AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) _LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], [0], [convert $build files to toolchain format])dnl ])# _LT_PATH_CONVERSION_FUNCTIONS mongodb-1.1.5/src/libbson/build/autotools/m4/ltoptions.m40000644000175000017500000003007312673034026023173 0ustar jmikolajmikola# Helper functions for option handling. -*- Autoconf -*- # # Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, # Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 7 ltoptions.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) # _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) # ------------------------------------------ m4_define([_LT_MANGLE_OPTION], [[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) # _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) # --------------------------------------- # Set option OPTION-NAME for macro MACRO-NAME, and if there is a # matching handler defined, dispatch to it. Other OPTION-NAMEs are # saved as a flag. m4_define([_LT_SET_OPTION], [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), _LT_MANGLE_DEFUN([$1], [$2]), [m4_warning([Unknown $1 option `$2'])])[]dnl ]) # _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) # ------------------------------------------------------------ # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. m4_define([_LT_IF_OPTION], [m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) # _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) # ------------------------------------------------------- # Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME # are set. m4_define([_LT_UNLESS_OPTIONS], [m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), [m4_define([$0_found])])])[]dnl m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 ])[]dnl ]) # _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) # ---------------------------------------- # OPTION-LIST is a space-separated list of Libtool options associated # with MACRO-NAME. If any OPTION has a matching handler declared with # LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about # the unknown option and exit. m4_defun([_LT_SET_OPTIONS], [# Set options m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [_LT_SET_OPTION([$1], _LT_Option)]) m4_if([$1],[LT_INIT],[ dnl dnl Simply set some default values (i.e off) if boolean options were not dnl specified: _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no ]) _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no ]) dnl dnl If no reference was made to various pairs of opposing options, then dnl we run the default mode handler for the pair. For example, if neither dnl `shared' nor `disable-shared' was passed, we enable building of shared dnl archives by default: _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], [_LT_ENABLE_FAST_INSTALL]) ]) ])# _LT_SET_OPTIONS ## --------------------------------- ## ## Macros to handle LT_INIT options. ## ## --------------------------------- ## # _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) # ----------------------------------------- m4_define([_LT_MANGLE_DEFUN], [[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) # LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) # ----------------------------------------------- m4_define([LT_OPTION_DEFINE], [m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl ])# LT_OPTION_DEFINE # dlopen # ------ LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes ]) AU_DEFUN([AC_LIBTOOL_DLOPEN], [_LT_SET_OPTION([LT_INIT], [dlopen]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `dlopen' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) # win32-dll # --------- # Declare package support for building win32 dll's. LT_OPTION_DEFINE([LT_INIT], [win32-dll], [enable_win32_dll=yes case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) AC_CHECK_TOOL(AS, as, false) AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(OBJDUMP, objdump, false) ;; esac test -z "$AS" && AS=as _LT_DECL([], [AS], [1], [Assembler program])dnl test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl ])# win32-dll AU_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_REQUIRE([AC_CANONICAL_HOST])dnl _LT_SET_OPTION([LT_INIT], [win32-dll]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `win32-dll' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) # _LT_ENABLE_SHARED([DEFAULT]) # ---------------------------- # implement the --enable-shared flag, and supports the `shared' and # `disable-shared' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_SHARED], [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([shared], [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) _LT_DECL([build_libtool_libs], [enable_shared], [0], [Whether or not to build shared libraries]) ])# _LT_ENABLE_SHARED LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) # Old names: AC_DEFUN([AC_ENABLE_SHARED], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) ]) AC_DEFUN([AC_DISABLE_SHARED], [_LT_SET_OPTION([LT_INIT], [disable-shared]) ]) AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_SHARED], []) dnl AC_DEFUN([AM_DISABLE_SHARED], []) # _LT_ENABLE_STATIC([DEFAULT]) # ---------------------------- # implement the --enable-static flag, and support the `static' and # `disable-static' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_STATIC], [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([static], [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_static=]_LT_ENABLE_STATIC_DEFAULT) _LT_DECL([build_old_libs], [enable_static], [0], [Whether or not to build static libraries]) ])# _LT_ENABLE_STATIC LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) # Old names: AC_DEFUN([AC_ENABLE_STATIC], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) ]) AC_DEFUN([AC_DISABLE_STATIC], [_LT_SET_OPTION([LT_INIT], [disable-static]) ]) AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_STATIC], []) dnl AC_DEFUN([AM_DISABLE_STATIC], []) # _LT_ENABLE_FAST_INSTALL([DEFAULT]) # ---------------------------------- # implement the --enable-fast-install flag, and support the `fast-install' # and `disable-fast-install' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_FAST_INSTALL], [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([fast-install], [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) _LT_DECL([fast_install], [enable_fast_install], [0], [Whether or not to optimize for fast installation])dnl ])# _LT_ENABLE_FAST_INSTALL LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) # Old names: AU_DEFUN([AC_ENABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `fast-install' option into LT_INIT's first parameter.]) ]) AU_DEFUN([AC_DISABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], [disable-fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `disable-fast-install' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) # _LT_WITH_PIC([MODE]) # -------------------- # implement the --with-pic flag, and support the `pic-only' and `no-pic' # LT_INIT options. # MODE is either `yes' or `no'. If omitted, it defaults to `both'. m4_define([_LT_WITH_PIC], [AC_ARG_WITH([pic], [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], [lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for lt_pkg in $withval; do IFS="$lt_save_ifs" if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS="$lt_save_ifs" ;; esac], [pic_mode=default]) test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl ])# _LT_WITH_PIC LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) # Old name: AU_DEFUN([AC_LIBTOOL_PICMODE], [_LT_SET_OPTION([LT_INIT], [pic-only]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `pic-only' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) ## ----------------- ## ## LTDL_INIT Options ## ## ----------------- ## m4_define([_LTDL_MODE], []) LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], [m4_define([_LTDL_MODE], [nonrecursive])]) LT_OPTION_DEFINE([LTDL_INIT], [recursive], [m4_define([_LTDL_MODE], [recursive])]) LT_OPTION_DEFINE([LTDL_INIT], [subproject], [m4_define([_LTDL_MODE], [subproject])]) m4_define([_LTDL_TYPE], []) LT_OPTION_DEFINE([LTDL_INIT], [installable], [m4_define([_LTDL_TYPE], [installable])]) LT_OPTION_DEFINE([LTDL_INIT], [convenience], [m4_define([_LTDL_TYPE], [convenience])]) mongodb-1.1.5/src/libbson/build/autotools/m4/ltsugar.m40000644000175000017500000001042412673034026022617 0ustar jmikolajmikola# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # # Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 6 ltsugar.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) # lt_join(SEP, ARG1, [ARG2...]) # ----------------------------- # Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their # associated separator. # Needed until we can rely on m4_join from Autoconf 2.62, since all earlier # versions in m4sugar had bugs. m4_define([lt_join], [m4_if([$#], [1], [], [$#], [2], [[$2]], [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) m4_define([_lt_join], [m4_if([$#$2], [2], [], [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) # lt_car(LIST) # lt_cdr(LIST) # ------------ # Manipulate m4 lists. # These macros are necessary as long as will still need to support # Autoconf-2.59 which quotes differently. m4_define([lt_car], [[$1]]) m4_define([lt_cdr], [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], [$#], 1, [], [m4_dquote(m4_shift($@))])]) m4_define([lt_unquote], $1) # lt_append(MACRO-NAME, STRING, [SEPARATOR]) # ------------------------------------------ # Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. # Note that neither SEPARATOR nor STRING are expanded; they are appended # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). # No SEPARATOR is output if MACRO-NAME was previously undefined (different # than defined and empty). # # This macro is needed until we can rely on Autoconf 2.62, since earlier # versions of m4sugar mistakenly expanded SEPARATOR but not STRING. m4_define([lt_append], [m4_define([$1], m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) # lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) # ---------------------------------------------------------- # Produce a SEP delimited list of all paired combinations of elements of # PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list # has the form PREFIXmINFIXSUFFIXn. # Needed until we can rely on m4_combine added in Autoconf 2.62. m4_define([lt_combine], [m4_if(m4_eval([$# > 3]), [1], [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl [[m4_foreach([_Lt_prefix], [$2], [m4_foreach([_Lt_suffix], ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) # lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) # ----------------------------------------------------------------------- # Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited # by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. m4_define([lt_if_append_uniq], [m4_ifdef([$1], [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], [lt_append([$1], [$2], [$3])$4], [$5])], [lt_append([$1], [$2], [$3])$4])]) # lt_dict_add(DICT, KEY, VALUE) # ----------------------------- m4_define([lt_dict_add], [m4_define([$1($2)], [$3])]) # lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) # -------------------------------------------- m4_define([lt_dict_add_subkey], [m4_define([$1($2:$3)], [$4])]) # lt_dict_fetch(DICT, KEY, [SUBKEY]) # ---------------------------------- m4_define([lt_dict_fetch], [m4_ifval([$3], m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) # lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) # ----------------------------------------------------------------- m4_define([lt_if_dict_fetch], [m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], [$5], [$6])]) # lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) # -------------------------------------------------------------- m4_define([lt_dict_filter], [m4_if([$5], [], [], [lt_join(m4_quote(m4_default([$4], [[, ]])), lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl ]) mongodb-1.1.5/src/libbson/build/autotools/m4/ltversion.m40000644000175000017500000000126212673034026023163 0ustar jmikolajmikola# ltversion.m4 -- version numbers -*- Autoconf -*- # # Copyright (C) 2004 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # @configure_input@ # serial 3337 ltversion.m4 # This file is part of GNU Libtool m4_define([LT_PACKAGE_VERSION], [2.4.2]) m4_define([LT_PACKAGE_REVISION], [1.3337]) AC_DEFUN([LTVERSION_VERSION], [macro_version='2.4.2' macro_revision='1.3337' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) mongodb-1.1.5/src/libbson/build/autotools/m4/lt~obsolete.m40000644000175000017500000001375612673034026023523 0ustar jmikolajmikola# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- # # Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004. # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 5 lt~obsolete.m4 # These exist entirely to fool aclocal when bootstrapping libtool. # # In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) # which have later been changed to m4_define as they aren't part of the # exported API, or moved to Autoconf or Automake where they belong. # # The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN # in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us # using a macro with the same name in our local m4/libtool.m4 it'll # pull the old libtool.m4 in (it doesn't see our shiny new m4_define # and doesn't know about Autoconf macros at all.) # # So we provide this file, which has a silly filename so it's always # included after everything else. This provides aclocal with the # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything # because those macros already exist, or will be overwritten later. # We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. # # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. # Yes, that means every name once taken will need to remain here until # we give up compatibility with versions before 1.7, at which point # we need to keep only those names which we still refer to. # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) mongodb-1.1.5/src/libbson/build/autotools/m4/pkg.m40000664000175000017500000001623112673034026021723 0ustar jmikolajmikola# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- # serial 1 (pkg-config-0.24) # # Copyright © 2004 Scott James Remnant . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # PKG_PROG_PKG_CONFIG([MIN-VERSION]) # ---------------------------------- AC_DEFUN([PKG_PROG_PKG_CONFIG], [m4_pattern_forbid([^_?PKG_[A-Z_]+$]) m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) fi if test -n "$PKG_CONFIG"; then _pkg_min_version=m4_default([$1], [0.9.0]) AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) PKG_CONFIG="" fi fi[]dnl ])# PKG_PROG_PKG_CONFIG # PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) # # Check to see whether a particular set of modules exists. Similar # to PKG_CHECK_MODULES(), but does not set variables or print errors. # # Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) # only at the first occurence in configure.ac, so if the first place # it's called might be skipped (such as if it is within an "if", you # have to call PKG_CHECK_EXISTS manually # -------------------------------------------------------------- AC_DEFUN([PKG_CHECK_EXISTS], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl if test -n "$PKG_CONFIG" && \ AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then m4_default([$2], [:]) m4_ifvaln([$3], [else $3])dnl fi]) # _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) # --------------------------------------------- m4_define([_PKG_CONFIG], [if test -n "$$1"; then pkg_cv_[]$1="$$1" elif test -n "$PKG_CONFIG"; then PKG_CHECK_EXISTS([$3], [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes ], [pkg_failed=yes]) else pkg_failed=untried fi[]dnl ])# _PKG_CONFIG # _PKG_SHORT_ERRORS_SUPPORTED # ----------------------------- AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], [AC_REQUIRE([PKG_PROG_PKG_CONFIG]) if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi[]dnl ])# _PKG_SHORT_ERRORS_SUPPORTED # PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], # [ACTION-IF-NOT-FOUND]) # # # Note that if there is a possibility the first call to # PKG_CHECK_MODULES might not happen, you should be sure to include an # explicit call to PKG_PROG_PKG_CONFIG in your configure.ac # # # -------------------------------------------------------------- AC_DEFUN([PKG_CHECK_MODULES], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl pkg_failed=no AC_MSG_CHECKING([for $1]) _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) _PKG_CONFIG([$1][_LIBS], [libs], [$2]) m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS and $1[]_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details.]) if test $pkg_failed = yes; then AC_MSG_RESULT([no]) _PKG_SHORT_ERRORS_SUPPORTED if test $_pkg_short_errors_supported = yes; then $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` else $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD m4_default([$4], [AC_MSG_ERROR( [Package requirements ($2) were not met: $$1_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. _PKG_TEXT])[]dnl ]) elif test $pkg_failed = untried; then AC_MSG_RESULT([no]) m4_default([$4], [AC_MSG_FAILURE( [The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. _PKG_TEXT To get pkg-config, see .])[]dnl ]) else $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS $1[]_LIBS=$pkg_cv_[]$1[]_LIBS AC_MSG_RESULT([yes]) $3 fi[]dnl ])# PKG_CHECK_MODULES # PKG_INSTALLDIR(DIRECTORY) # ------------------------- # Substitutes the variable pkgconfigdir as the location where a module # should install pkg-config .pc files. By default the directory is # $libdir/pkgconfig, but the default can be changed by passing # DIRECTORY. The user can override through the --with-pkgconfigdir # parameter. AC_DEFUN([PKG_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) m4_pushdef([pkg_description], [pkg-config installation directory @<:@]pkg_default[@:>@]) AC_ARG_WITH([pkgconfigdir], [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, [with_pkgconfigdir=]pkg_default) AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) ]) dnl PKG_INSTALLDIR # PKG_NOARCH_INSTALLDIR(DIRECTORY) # ------------------------- # Substitutes the variable noarch_pkgconfigdir as the location where a # module should install arch-independent pkg-config .pc files. By # default the directory is $datadir/pkgconfig, but the default can be # changed by passing DIRECTORY. The user can override through the # --with-noarch-pkgconfigdir parameter. AC_DEFUN([PKG_NOARCH_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) m4_pushdef([pkg_description], [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) AC_ARG_WITH([noarch-pkgconfigdir], [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, [with_noarch_pkgconfigdir=]pkg_default) AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) ]) dnl PKG_NOARCH_INSTALLDIR mongodb-1.1.5/src/libbson/build/autotools/m4/silent.m40000664000175000017500000000267212673034026022444 0ustar jmikolajmikoladnl Use GNU make's -s when available dnl dnl Copyright (c) 2010, Damien Lespiau dnl dnl DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE dnl TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION dnl dnl 0. You just DO WHAT THE FUCK YOU WANT TO. dnl dnl The above copyright notice and this permission notice shall be dnl included in all copies or substantial portions of the Software. dnl dnl Simply put this file in your m4 macro directory (as everyone should be dnl using AC_CONFIG_MACRO_DIR by now!) and add AS_AM_REALLY_SILENT somewhere dnl in your configure.ac AC_DEFUN([AS_AM_REALLY_SILENT], [ AC_MSG_CHECKING([whether ${MAKE-make} can be made more silent]) dnl And we even cache that FFS! AC_CACHE_VAL( [as_cv_prog_make_can_be_really_silent], [cat >confstfu.make <<\_WTF SHELL = /bin/sh all: @echo '@@@%%%clutter rocks@@@%%%' _WTF as_cv_prog_make_can_be_really_silent=no case `${MAKE-make} -f confstfu.make -s --no-print-directory 2>/dev/null` in *'@@@%%%clutter rocks@@@%%%'*) test $? = 0 && as_cv_prog_make_can_be_really_silent=yes esac rm -f confstfu.make]) if test $as_cv_prog_make_can_be_really_silent = yes; then AC_MSG_RESULT([yes]) make_flags='`\ if test "x$(AM_DEFAULT_VERBOSITY)" = x0; then \ test -z "$V" -o "x$V" = x0 && echo -s; \ else \ test "x$V" = x0 && echo -s; \ fi`' AC_SUBST([AM_MAKEFLAGS], [$make_flags]) else AC_MSG_RESULT([no]) fi ]) mongodb-1.1.5/src/libbson/build/autotools/AutoHarden.m40000664000175000017500000000500412673034026022650 0ustar jmikolajmikola# We want to check for compiler flag support, but there is no way to make # clang's "argument unused" warning fatal. So we invoke the compiler through a # wrapper script that greps for this message. saved_CC="$CC" saved_CXX="$CXX" saved_LD="$LD" flag_wrap="$srcdir/build/autotools/scripts/wrap-compiler-for-flag-check" CC="$flag_wrap $CC" CXX="$flag_wrap $CXX" LD="$flag_wrap $LD" # We use the same hardening flags for C and C++. We must check that each flag # is supported by both compilers. AC_DEFUN([check_cc_cxx_flag], [AC_LANG_PUSH(C) AX_CHECK_COMPILE_FLAG([$1], [AC_LANG_PUSH(C++) AX_CHECK_COMPILE_FLAG([$1], [$2], [$3], [-Werror $4]) AC_LANG_POP(C++)], [$3], [-Werror $4]) AC_LANG_POP(C)]) AC_DEFUN([check_link_flag], [AX_CHECK_LINK_FLAG([$1], [$2], [$3], [-Werror $4])]) AC_ARG_ENABLE([hardening], [AS_HELP_STRING([--enable-hardening], [Enable compiler and linker options to frustrate memory corruption exploits @<:@yes@:>@])], [enable_hardening="$enableval"], [enable_hardening="yes"]) HARDEN_CFLAGS="" HARDEN_LDFLAGS="" AS_IF([test x"$enable_hardening" != x"no"], [ check_cc_cxx_flag([-fno-strict-overflow], [HARDEN_CFLAGS="$HARDEN_CFLAGS -fno-strict-overflow"]) # This one will likely succeed, even on platforms where it does nothing. check_cc_cxx_flag([-D_FORTIFY_SOURCE=2], [HARDEN_CFLAGS="$HARDEN_CFLAGS -D_FORTIFY_SOURCE=2"]) check_cc_cxx_flag([-fstack-protector-all], [check_link_flag([-fstack-protector-all], [HARDEN_CFLAGS="$HARDEN_CFLAGS -fstack-protector-all" check_cc_cxx_flag([-Wstack-protector], [HARDEN_CFLAGS="$HARDEN_CFLAGS -Wstack-protector"], [], [-fstack-protector-all]) check_cc_cxx_flag([--param ssp-buffer-size=1], [HARDEN_CFLAGS="$HARDEN_CFLAGS --param ssp-buffer-size=1"], [], [-fstack-protector-all])])]) # At the link step, we might want -pie (GCC) or -Wl,-pie (Clang on OS X) # # The linker checks also compile code, so we need to include -fPIE as well. check_cc_cxx_flag([-fPIE], [check_link_flag([-fPIE -pie], [HARDEN_CFLAGS="$HARDEN_CFLAGS -fPIE" HARDEN_LDFLAGS="$HARDEN_LDFLAGS -pie"], [check_link_flag([-fPIE -Wl,-pie], [HARDEN_CFLAGS="$HARDEN_CFLAGS -fPIE" HARDEN_LDFLAGS="$HARDEN_LDFLAGS -Wl,-pie"])])]) check_link_flag([-Wl,-z,relro], [HARDEN_LDFLAGS="$HARDEN_LDFLAGS -Wl,-z,relro" check_link_flag([-Wl,-z,now], [HARDEN_LDFLAGS="$HARDEN_LDFLAGS -Wl,-z,now"])])]) AC_SUBST([HARDEN_CFLAGS]) AC_SUBST([HARDEN_LDFLAGS]) # End of flag tests. CC="$saved_CC" CXX="$saved_CXX" LD="$saved_LD" mongodb-1.1.5/src/libbson/build/autotools/CheckAtomics.m40000664000175000017500000000211212673034026023150 0ustar jmikolajmikolaAC_LANG_PUSH([C]) AC_MSG_CHECKING([for __sync_add_and_fetch_4]) AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[int32_t v = 1; return __sync_add_and_fetch_4 (&v, (int32_t)10);]])], [AC_MSG_RESULT(yes) have_sync_add_and_fetch_4=yes], [AC_MSG_RESULT(no) have_sync_add_and_fetch_4=no]) AS_IF([test "$have_sync_add_and_fetch_4" = "yes"], [AC_SUBST(BSON_HAVE_ATOMIC_32_ADD_AND_FETCH, 1)], [AC_SUBST(BSON_HAVE_ATOMIC_32_ADD_AND_FETCH, 0)]) AC_MSG_CHECKING([for __sync_add_and_fetch_8]) AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[int64_t v; return __sync_add_and_fetch_8 (&v, (int64_t)10);]])], [AC_MSG_RESULT(yes) have_sync_add_and_fetch_8=yes], [AC_MSG_RESULT(no) have_sync_add_and_fetch_8=no]) AS_IF([test "$have_sync_add_and_fetch_8" = "yes"], [AC_SUBST(BSON_HAVE_ATOMIC_64_ADD_AND_FETCH, 1)], [AC_SUBST(BSON_HAVE_ATOMIC_64_ADD_AND_FETCH, 0)]) AC_LANG_POP([C]) mongodb-1.1.5/src/libbson/build/autotools/CheckCompiler.m40000664000175000017500000000341612673034026023333 0ustar jmikolajmikola# If CFLAGS and CXXFLAGS are unset, default to empty. # This is to tell automake not to include '-g' if C{XX,}FLAGS is not set. # For more info - http://www.gnu.org/software/automake/manual/autoconf.html#C_002b_002b-Compiler if test -z "$CXXFLAGS"; then CXXFLAGS="" fi if test -z "$CFLAGS"; then CFLAGS="" fi AC_PROG_CC AC_PROG_CXX # Check that an appropriate C compiler is available. c_compiler="unknown" AC_LANG_PUSH([C]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([ #if !(defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER)) #error Not a supported GCC compiler #endif #if defined(__GNUC__) #define GCC_VERSION (__GNUC__ * 10000 \ + __GNUC_MINOR__ * 100 \ + __GNUC_PATCHLEVEL__) #if GCC_VERSION < 40100 #error Not a supported GCC compiler #endif #endif ])], [c_compiler="gcc"], []) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([ #if defined(__clang__) #define CLANG_VERSION (__clang_major__ * 10000 \ + __clang_minor__ * 100 \ + __clang_patchlevel__) #if CLANG_VERSION < 30300 #error Not a supported Clang compiler #endif #endif ])], [c_compiler="clang"], []) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([ #if !(defined(__SUNPRO_C)) #error Not a supported Sun compiler #endif ])], [c_compiler="sun"], []) AC_LANG_POP([C]) if test "$c_compiler" = "unknown"; then AC_MSG_ERROR([Compiler GCC >= 4.1 or Clang >= 3.3 is required for C compilation]) fi # GLibc 2.19 complains about both _BSD_SOURCE and _GNU_SOURCE. The _GNU_SOURCE # contains everything anyway. So just use that. AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #ifndef __GLIBC__ #error not glibc #endif ]], [])], LIBC_FEATURES="-D_GNU_SOURCE", LIBC_FEATURES="-D_BSD_SOURCE") AC_SUBST(LIBC_FEATURES) AC_C_CONST AC_C_INLINE AC_C_TYPEOF mongodb-1.1.5/src/libbson/build/autotools/CheckHeaders.m40000664000175000017500000000026612673034026023134 0ustar jmikolajmikolaAC_HEADER_STDBOOL AC_SUBST(BSON_HAVE_STDBOOL_H, 0) if test "$ac_cv_header_stdbool_h" = "yes"; then AC_SUBST(BSON_HAVE_STDBOOL_H, 1) fi AC_CREATE_STDINT_H([src/bson/bson-stdint.h]) mongodb-1.1.5/src/libbson/build/autotools/CheckHost.m40000664000175000017500000000135512673034026022476 0ustar jmikolajmikolaAC_CANONICAL_HOST os_win32=no os_linux=no os_freebsd=no os_gnu=no case "$host" in *-mingw*|*-*-cygwin*) os_win32=yes TARGET_OS=windows ;; *-*-*netbsd*) os_netbsd=yes TARGET_OS=unix ;; *-*-*freebsd*) os_freebsd=yes TARGET_OS=unix ;; *-*-*openbsd*) os_openbsd=yes TARGET_OS=unix ;; *-*-linux*) os_linux=yes os_gnu=yes TARGET_OS=unix ;; *-*-solaris*) os_solaris=yes TARGET_OS=unix ;; *-*-darwin*) os_darwin=yes TARGET_OS=unix ;; gnu*|k*bsd*-gnu*) os_gnu=yes TARGET_OS=unix ;; *) AC_MSG_WARN([*** Please add $host to configure.ac checks!]) ;; esac mongodb-1.1.5/src/libbson/build/autotools/CheckProgs.m40000664000175000017500000000062212673034026022647 0ustar jmikolajmikolaAC_PATH_PROG(PERL, perl) if test -z "$PERL"; then AC_MSG_ERROR([You need 'perl' to compile libbson]) fi AC_PATH_PROG(MV, mv) if test -z "$MV"; then AC_MSG_ERROR([You need 'mv' to compile libbson]) fi AC_PATH_PROG(GREP, grep) if test -z "$GREP"; then AC_MSG_ERROR([You need 'grep' to compile libbson]) fi # Optional for documentation AC_PATH_PROG(YELP_BUILD, yelp-build) AC_PROG_INSTALL mongodb-1.1.5/src/libbson/build/autotools/CheckTarget.m40000664000175000017500000000114712673034026023006 0ustar jmikolajmikolaAC_CANONICAL_SYSTEM enable_crosscompile=no if test "x$host" != "x$target"; then enable_crosscompile=yes case "$target" in *-mingw*|*-*-cygwin*) TARGET_OS=windows ;; arm*-darwin*) TARGET_OS=unix ;; powerpc64-*-linux-gnu) TARGET_OS=unix ;; arm*-linux-*) TARGET_OS=unix ;; *) AC_MSG_ERROR([Cross compiling is not supported for target $target]) ;; esac fi AC_SUBST(BSON_OS, 1) if test "$TARGET_OS" = "windows"; then AC_SUBST(BSON_OS, 2) fi mongodb-1.1.5/src/libbson/build/autotools/Coverage.m40000664000175000017500000000031412673034026022350 0ustar jmikolajmikolaCOVERAGE_CFLAGS="" COVERAGE_LDFLAGS="" if test "$enable_coverage" = "yes"; then COVERAGE_CFLAGS="--coverage -g" COVERAGE_LDFLAGS="-lgcov" fi AC_SUBST(COVERAGE_CFLAGS) AC_SUBST(COVERAGE_LDFLAGS) mongodb-1.1.5/src/libbson/build/autotools/Endian.m40000664000175000017500000000026012673034026022013 0ustar jmikolajmikolaenable_bigendian=no AC_C_BIGENDIAN AC_SUBST(BSON_BYTE_ORDER, 1234) if test "x$ac_cv_c_bigendian" = "xyes"; then AC_SUBST(BSON_BYTE_ORDER, 4321) enable_bigendian=yes fi mongodb-1.1.5/src/libbson/build/autotools/FindDependencies.m40000664000175000017500000000440412673034026024010 0ustar jmikolajmikola# Check for strnlen() AC_SUBST(BSON_HAVE_STRNLEN, 0) AC_CHECK_FUNC(strnlen, [AC_SUBST(BSON_HAVE_STRNLEN, 1)]) # Check for snprintf() AC_SUBST(BSON_HAVE_SNPRINTF, 0) AC_CHECK_FUNC(snprintf, [AC_SUBST(BSON_HAVE_SNPRINTF, 1)]) # Check for _set_output_format (unlikely, only Visual Studio 2013 and older) AC_SUBST(BSON_NEEDS_SET_OUTPUT_FORMAT, 0) AC_CHECK_FUNCS(_set_output_format, [AC_SUBST(BSON_NEEDS_SET_OUTPUT_FORMAT, 1)]) # Check for struct timespec AC_SUBST(BSON_HAVE_TIMESPEC, 0) AC_CHECK_TYPES([struct timespec], [AC_SUBST(BSON_HAVE_TIMESPEC, 1)]) # Check for clock_gettime and if it needs -lrt AC_SUBST(BSON_HAVE_CLOCK_GETTIME, 0) AC_SEARCH_LIBS([clock_gettime], [rt], [AC_SUBST(BSON_HAVE_CLOCK_GETTIME, 1)]) # Check for pthreads. We might need to make this better to handle mingw, # but I actually think it is okay to just check for it even though we will # use win32 primatives. AX_PTHREAD([], [AC_MSG_ERROR([libbson requires pthreads on non-Windows platforms.])]) # The following is borrowed from the guile configure script. # # On past versions of Solaris, believe 8 through 10 at least, you # had to write "pthread_once_t foo = { PTHREAD_ONCE_INIT };". # This is contrary to POSIX: # http://www.opengroup.org/onlinepubs/000095399/functions/pthread_once.html # Check here if this style is required. # # glibc (2.3.6 at least) works both with or without braces, so the # test checks whether it works without. # AC_SUBST(BSON_PTHREAD_ONCE_INIT_NEEDS_BRACES, 0) AC_CACHE_CHECK([whether PTHREAD_ONCE_INIT needs braces], bson_cv_need_braces_on_pthread_once_init, [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include pthread_once_t foo = PTHREAD_ONCE_INIT;]])], [bson_cv_need_braces_on_pthread_once_init=no], [bson_cv_need_braces_on_pthread_once_init=yes])]) if test "$bson_cv_need_braces_on_pthread_once_init" = yes; then AC_SUBST(BSON_PTHREAD_ONCE_INIT_NEEDS_BRACES, 1) fi # Solaris needs to link against socket libs. # This is only used in our streaming bson examples if test "$os_solaris" = "yes"; then SOCKET_CFLAGS="$CFLAGS -D__EXTENSIONS__" SOCKET_CFLAGS="$CFLAGS -D_XOPEN_SOURCE=1" SOCKET_CFLAGS="$CFLAGS -D_XOPEN_SOURCE_EXTENDED=1" SOCKET_LDFLAGS="$LDFLAGS -lsocket -lnsl" AC_SUBST(SOCKET_CFLAGS) AC_SUBST(SOCKET_LDFLAGS) fi mongodb-1.1.5/src/libbson/build/autotools/LDVersionScript.m40000664000175000017500000000341412673034026023653 0ustar jmikolajmikola# ld-version-script.m4 serial 3 dnl Copyright (C) 2008-2013 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl From Simon Josefsson # FIXME: The test below returns a false positive for mingw # cross-compiles, 'local:' statements does not reduce number of # exported symbols in a DLL. Use --disable-ld-version-script to work # around the problem. # gl_LD_VERSION_SCRIPT # -------------------- # Check if LD supports linker scripts, and define automake conditional # HAVE_LD_VERSION_SCRIPT if so. AC_DEFUN([gl_LD_VERSION_SCRIPT], [ AC_ARG_ENABLE([ld-version-script], AS_HELP_STRING([--enable-ld-version-script], [enable linker version script (default is enabled when possible)]), [have_ld_version_script=$enableval], []) if test -z "$have_ld_version_script"; then AC_MSG_CHECKING([if LD -Wl,--version-script works]) save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -Wl,--version-script=conftest.map" cat > conftest.map < conftest.map <@], [Use strict compiler flags @<:@default=]maintainer_flags_default[@:>@])], [], [enable_maintainer_flags=maintainer_flags_default]) AC_ARG_ENABLE([html-docs], [AS_HELP_STRING([--enable-html-docs=@<:@yes/no@:>@], [Build HTML documentation.])], [], [enable_html_docs=no]) AC_ARG_ENABLE([man-pages], [AS_HELP_STRING([--enable-man-pages=@<:@yes/no@:>@], [Build and install man-pages.])], [], [enable_man_pages=no]) AC_ARG_ENABLE([yelp], [AS_HELP_STRING([--enable-yelp=@<:@yes/no@:>@], [Install yelp manuals.])], [], [enable_yelp=no]) mongodb-1.1.5/src/libbson/build/autotools/SetupAutomake.m40000664000175000017500000000255012673034026023410 0ustar jmikolajmikolam4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) AM_PROG_CC_C_O # OS Conditionals. AM_CONDITIONAL([OS_WIN32],[test "$os_win32" = "yes"]) AM_CONDITIONAL([OS_UNIX],[test "$os_win32" = "no"]) AM_CONDITIONAL([OS_LINUX],[test "$os_linux" = "yes"]) AM_CONDITIONAL([OS_GNU],[test "$os_gnu" = "yes"]) AM_CONDITIONAL([OS_DARWIN],[test "$os_darwin" = "yes"]) AM_CONDITIONAL([OS_FREEBSD],[test "$os_freebsd" = "yes"]) # Compiler Conditionals. AM_CONDITIONAL([COMPILER_GCC],[test "$c_compiler" = "gcc" && test "$cxx_compiler" = "g++"]) AM_CONDITIONAL([COMPILER_CLANG],[test "$c_compiler" = "clang" && test "$cxx_compiler" = "clang++"]) # Feature Conditionals AM_CONDITIONAL([ENABLE_DEBUG],[test "$enable_debug" = "yes"]) # C99 Features AM_CONDITIONAL([ENABLE_STDBOOL],[test "$enable_stdbool" = "yes"]) # Should we use pthreads AM_CONDITIONAL([ENABLE_PTHREADS], test "$enable_pthreads" = "yes") # Can we run the abicheck? AM_CONDITIONAL([CAN_ABI_CHECK], [test "os_linux" = "yes" && test "$have_sync_add_and_fetch_8" = "yes"]) # Should we build man pages AM_CONDITIONAL([ENABLE_MAN_PAGES],[test "$enable_man_pages" = "yes"]) # Should we build HTML documentation AM_CONDITIONAL([ENABLE_HTML_DOCS],[test "$enable_html_docs" = "yes"]) AS_IF([test "$enable_html_docs" = "yes" && test -z "$YELP_BUILD"], [AC_MSG_ERROR([yelp-build must be installed to generate HTML documentation.])]) mongodb-1.1.5/src/libbson/build/autotools/SetupLibtool.m40000664000175000017500000000011112673034026023235 0ustar jmikolajmikolaLT_PREREQ([2.2]) AC_DISABLE_STATIC AC_LIBTOOL_WIN32_DLL AC_PROG_LIBTOOL mongodb-1.1.5/src/libbson/build/autotools/Versions.m40000664000175000017500000000316512673034026022434 0ustar jmikolajmikolaBSON_CURRENT_FILE=${srcdir}/VERSION_CURRENT BSON_VERSION=$(cat $BSON_CURRENT_FILE) BSON_MAJOR_VERSION=$(cut -d- -f1 $BSON_CURRENT_FILE | cut -d. -f1) BSON_MINOR_VERSION=$(cut -d- -f1 $BSON_CURRENT_FILE | cut -d. -f2) BSON_MICRO_VERSION=$(cut -d- -f1 $BSON_CURRENT_FILE | cut -d. -f3) BSON_PRERELEASE_VERSION=$(cut -s -d- -f2 $BSON_CURRENT_FILE) AC_SUBST(BSON_VERSION) AC_SUBST(BSON_MAJOR_VERSION) AC_SUBST(BSON_MINOR_VERSION) AC_SUBST(BSON_MICRO_VERSION) AC_SUBST(BSON_PRERELEASE_VERSION) BSON_RELEASED_FILE=${srcdir}/VERSION_RELEASED BSON_RELEASED_VERSION=$(cat $BSON_RELEASED_FILE) BSON_RELEASED_MAJOR_VERSION=$(cut -d- -f1 $BSON_RELEASED_FILE | cut -d. -f1) BSON_RELEASED_MINOR_VERSION=$(cut -d- -f1 $BSON_RELEASED_FILE | cut -d. -f2) BSON_RELEASED_MICRO_VERSION=$(cut -d- -f1 $BSON_RELEASED_FILE | cut -d. -f3) BSON_RELEASED_PRERELEASE_VERSION=$(cut -s -d- -f2 $BSON_RELEASED_FILE) AC_SUBST(BSON_RELEASED_VERSION) AC_SUBST(BSON_RELEASED_MAJOR_VERSION) AC_SUBST(BSON_RELEASED_MINOR_VERSION) AC_SUBST(BSON_RELEASED_MICRO_VERSION) AC_SUBST(BSON_RELEASED_PRERELEASE_VERSION) AC_MSG_NOTICE([Current version (from VERSION_CURRENT file): $BSON_VERSION]) if test "x$BSON_RELEASED_PRERELEASE_VERSION" != "x"; then AC_ERROR([RELEASED_VERSION file has prerelease version $BSON_RELEASED_VERSION]) fi if test "x$BSON_VERSION" != "x$BSON_RELEASED_VERSION"; then AC_MSG_NOTICE([Most recent release (from VERSION_RELEASED file): $BSON_RELEASED_VERSION]) if test "x$BSON_PRERELEASE_VERSION" = "x"; then AC_ERROR([Current version ($BSON_PRERELEASE_VERSION) must be a prerelease (with "-dev", "-beta", etc.) or equal to previous release]) fi fi mongodb-1.1.5/src/libbson/src/bson/b64_ntop.h0000664000175000017500000001655612673034026020576 0ustar jmikolajmikola/* * Copyright (c) 1996, 1998 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. */ /* * Portions Copyright (c) 1995 by International Business Machines, Inc. * * International Business Machines, Inc. (hereinafter called IBM) grants * permission under its copyrights to use, copy, modify, and distribute this * Software with or without fee, provided that the above copyright notice and * all paragraphs of this notice appear in all copies, and that the name of IBM * not be used in connection with the marketing of any product incorporating * the Software or modifications thereof, without specific, written prior * permission. * * To the extent it has a right to do so, IBM grants an immunity from suit * under its patents, if any, for the use, sale or manufacture of products to * the extent that such products are used for performing Domain Name System * dynamic updates in TCP/IP networks by means of the Software. No immunity is * granted for any product per se or for any other function of any product. * * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. */ #include "bson-compat.h" #include "bson-macros.h" #include "bson-types.h" #define Assert(Cond) if (!(Cond)) abort () static const char Base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; static const char Pad64 = '='; /* (From RFC1521 and draft-ietf-dnssec-secext-03.txt) * The following encoding technique is taken from RFC 1521 by Borenstein * and Freed. It is reproduced here in a slightly edited form for * convenience. * * A 65-character subset of US-ASCII is used, enabling 6 bits to be * represented per printable character. (The extra 65th character, "=", * is used to signify a special processing function.) * * The encoding process represents 24-bit groups of input bits as output * strings of 4 encoded characters. Proceeding from left to right, a * 24-bit input group is formed by concatenating 3 8-bit input groups. * These 24 bits are then treated as 4 concatenated 6-bit groups, each * of which is translated into a single digit in the base64 alphabet. * * Each 6-bit group is used as an index into an array of 64 printable * characters. The character referenced by the index is placed in the * output string. * * Table 1: The Base64 Alphabet * * Value Encoding Value Encoding Value Encoding Value Encoding * 0 A 17 R 34 i 51 z * 1 B 18 S 35 j 52 0 * 2 C 19 T 36 k 53 1 * 3 D 20 U 37 l 54 2 * 4 E 21 V 38 m 55 3 * 5 F 22 W 39 n 56 4 * 6 G 23 X 40 o 57 5 * 7 H 24 Y 41 p 58 6 * 8 I 25 Z 42 q 59 7 * 9 J 26 a 43 r 60 8 * 10 K 27 b 44 s 61 9 * 11 L 28 c 45 t 62 + * 12 M 29 d 46 u 63 / * 13 N 30 e 47 v * 14 O 31 f 48 w (pad) = * 15 P 32 g 49 x * 16 Q 33 h 50 y * * Special processing is performed if fewer than 24 bits are available * at the end of the data being encoded. A full encoding quantum is * always completed at the end of a quantity. When fewer than 24 input * bits are available in an input group, zero bits are added (on the * right) to form an integral number of 6-bit groups. Padding at the * end of the data is performed using the '=' character. * * Since all base64 input is an integral number of octets, only the * following cases can arise: * * (1) the final quantum of encoding input is an integral * multiple of 24 bits; here, the final unit of encoded * output will be an integral multiple of 4 characters * with no "=" padding, * (2) the final quantum of encoding input is exactly 8 bits; * here, the final unit of encoded output will be two * characters followed by two "=" padding characters, or * (3) the final quantum of encoding input is exactly 16 bits; * here, the final unit of encoded output will be three * characters followed by one "=" padding character. */ static ssize_t b64_ntop (uint8_t const *src, size_t srclength, char *target, size_t targsize) { size_t datalength = 0; uint8_t input[3]; uint8_t output[4]; size_t i; while (2 < srclength) { input[0] = *src++; input[1] = *src++; input[2] = *src++; srclength -= 3; output[0] = input[0] >> 2; output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); output[3] = input[2] & 0x3f; Assert (output[0] < 64); Assert (output[1] < 64); Assert (output[2] < 64); Assert (output[3] < 64); if (datalength + 4 > targsize) { return -1; } target[datalength++] = Base64[output[0]]; target[datalength++] = Base64[output[1]]; target[datalength++] = Base64[output[2]]; target[datalength++] = Base64[output[3]]; } /* Now we worry about padding. */ if (0 != srclength) { /* Get what's left. */ input[0] = input[1] = input[2] = '\0'; for (i = 0; i < srclength; i++) { input[i] = *src++; } output[0] = input[0] >> 2; output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); Assert (output[0] < 64); Assert (output[1] < 64); Assert (output[2] < 64); if (datalength + 4 > targsize) { return -1; } target[datalength++] = Base64[output[0]]; target[datalength++] = Base64[output[1]]; if (srclength == 1) { target[datalength++] = Pad64; } else{ target[datalength++] = Base64[output[2]]; } target[datalength++] = Pad64; } if (datalength >= targsize) { return -1; } target[datalength] = '\0'; /* Returned value doesn't count \0. */ return datalength; } mongodb-1.1.5/src/libbson/src/bson/b64_pton.h0000664000175000017500000002602312673034026020564 0ustar jmikolajmikola/* * Copyright (c) 1996, 1998 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. */ /* * Portions Copyright (c) 1995 by International Business Machines, Inc. * * International Business Machines, Inc. (hereinafter called IBM) grants * permission under its copyrights to use, copy, modify, and distribute this * Software with or without fee, provided that the above copyright notice and * all paragraphs of this notice appear in all copies, and that the name of IBM * not be used in connection with the marketing of any product incorporating * the Software or modifications thereof, without specific, written prior * permission. * * To the extent it has a right to do so, IBM grants an immunity from suit * under its patents, if any, for the use, sale or manufacture of products to * the extent that such products are used for performing Domain Name System * dynamic updates in TCP/IP networks by means of the Software. No immunity is * granted for any product per se or for any other function of any product. * * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. */ #include "bson-compat.h" #define Assert(Cond) if (!(Cond)) abort() static const char Base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; static const char Pad64 = '='; /* (From RFC1521 and draft-ietf-dnssec-secext-03.txt) The following encoding technique is taken from RFC 1521 by Borenstein and Freed. It is reproduced here in a slightly edited form for convenience. A 65-character subset of US-ASCII is used, enabling 6 bits to be represented per printable character. (The extra 65th character, "=", is used to signify a special processing function.) The encoding process represents 24-bit groups of input bits as output strings of 4 encoded characters. Proceeding from left to right, a 24-bit input group is formed by concatenating 3 8-bit input groups. These 24 bits are then treated as 4 concatenated 6-bit groups, each of which is translated into a single digit in the base64 alphabet. Each 6-bit group is used as an index into an array of 64 printable characters. The character referenced by the index is placed in the output string. Table 1: The Base64 Alphabet Value Encoding Value Encoding Value Encoding Value Encoding 0 A 17 R 34 i 51 z 1 B 18 S 35 j 52 0 2 C 19 T 36 k 53 1 3 D 20 U 37 l 54 2 4 E 21 V 38 m 55 3 5 F 22 W 39 n 56 4 6 G 23 X 40 o 57 5 7 H 24 Y 41 p 58 6 8 I 25 Z 42 q 59 7 9 J 26 a 43 r 60 8 10 K 27 b 44 s 61 9 11 L 28 c 45 t 62 + 12 M 29 d 46 u 63 / 13 N 30 e 47 v 14 O 31 f 48 w (pad) = 15 P 32 g 49 x 16 Q 33 h 50 y Special processing is performed if fewer than 24 bits are available at the end of the data being encoded. A full encoding quantum is always completed at the end of a quantity. When fewer than 24 input bits are available in an input group, zero bits are added (on the right) to form an integral number of 6-bit groups. Padding at the end of the data is performed using the '=' character. Since all base64 input is an integral number of octets, only the following cases can arise: (1) the final quantum of encoding input is an integral multiple of 24 bits; here, the final unit of encoded output will be an integral multiple of 4 characters with no "=" padding, (2) the final quantum of encoding input is exactly 8 bits; here, the final unit of encoded output will be two characters followed by two "=" padding characters, or (3) the final quantum of encoding input is exactly 16 bits; here, the final unit of encoded output will be three characters followed by one "=" padding character. */ /* skips all whitespace anywhere. converts characters, four at a time, starting at (or after) src from base - 64 numbers into three 8 bit bytes in the target area. it returns the number of data bytes stored at the target, or -1 on error. */ static int b64rmap_initialized = 0; static uint8_t b64rmap[256]; static const uint8_t b64rmap_special = 0xf0; static const uint8_t b64rmap_end = 0xfd; static const uint8_t b64rmap_space = 0xfe; static const uint8_t b64rmap_invalid = 0xff; /** * Initializing the reverse map is not thread safe. * Which is fine for NSD. For now... **/ static void b64_initialize_rmap () { int i; unsigned char ch; /* Null: end of string, stop parsing */ b64rmap[0] = b64rmap_end; for (i = 1; i < 256; ++i) { ch = (unsigned char)i; /* Whitespaces */ if (isspace(ch)) b64rmap[i] = b64rmap_space; /* Padding: stop parsing */ else if (ch == Pad64) b64rmap[i] = b64rmap_end; /* Non-base64 char */ else b64rmap[i] = b64rmap_invalid; } /* Fill reverse mapping for base64 chars */ for (i = 0; Base64[i] != '\0'; ++i) b64rmap[(uint8_t)Base64[i]] = i; b64rmap_initialized = 1; } static int b64_pton_do(char const *src, uint8_t *target, size_t targsize) { int tarindex, state, ch; uint8_t ofs; state = 0; tarindex = 0; while (1) { ch = *src++; ofs = b64rmap[ch]; if (ofs >= b64rmap_special) { /* Ignore whitespaces */ if (ofs == b64rmap_space) continue; /* End of base64 characters */ if (ofs == b64rmap_end) break; /* A non-base64 character. */ return (-1); } switch (state) { case 0: if ((size_t)tarindex >= targsize) return (-1); target[tarindex] = ofs << 2; state = 1; break; case 1: if ((size_t)tarindex + 1 >= targsize) return (-1); target[tarindex] |= ofs >> 4; target[tarindex+1] = (ofs & 0x0f) << 4 ; tarindex++; state = 2; break; case 2: if ((size_t)tarindex + 1 >= targsize) return (-1); target[tarindex] |= ofs >> 2; target[tarindex+1] = (ofs & 0x03) << 6; tarindex++; state = 3; break; case 3: if ((size_t)tarindex >= targsize) return (-1); target[tarindex] |= ofs; tarindex++; state = 0; break; default: abort(); } } /* * We are done decoding Base-64 chars. Let's see if we ended * on a byte boundary, and/or with erroneous trailing characters. */ if (ch == Pad64) { /* We got a pad char. */ ch = *src++; /* Skip it, get next. */ switch (state) { case 0: /* Invalid = in first position */ case 1: /* Invalid = in second position */ return (-1); case 2: /* Valid, means one byte of info */ /* Skip any number of spaces. */ for ((void)NULL; ch != '\0'; ch = *src++) if (b64rmap[ch] != b64rmap_space) break; /* Make sure there is another trailing = sign. */ if (ch != Pad64) return (-1); ch = *src++; /* Skip the = */ /* Fall through to "single trailing =" case. */ /* FALLTHROUGH */ case 3: /* Valid, means two bytes of info */ /* * We know this char is an =. Is there anything but * whitespace after it? */ for ((void)NULL; ch != '\0'; ch = *src++) if (b64rmap[ch] != b64rmap_space) return (-1); /* * Now make sure for cases 2 and 3 that the "extra" * bits that slopped past the last full byte were * zeros. If we don't check them, they become a * subliminal channel. */ if (target[tarindex] != 0) return (-1); default: break; } } else { /* * We ended by seeing the end of the string. Make sure we * have no partial bytes lying around. */ if (state != 0) return (-1); } return (tarindex); } static int b64_pton_len(char const *src) { int tarindex, state, ch; uint8_t ofs; state = 0; tarindex = 0; while (1) { ch = *src++; ofs = b64rmap[ch]; if (ofs >= b64rmap_special) { /* Ignore whitespaces */ if (ofs == b64rmap_space) continue; /* End of base64 characters */ if (ofs == b64rmap_end) break; /* A non-base64 character. */ return (-1); } switch (state) { case 0: state = 1; break; case 1: tarindex++; state = 2; break; case 2: tarindex++; state = 3; break; case 3: tarindex++; state = 0; break; default: abort(); } } /* * We are done decoding Base-64 chars. Let's see if we ended * on a byte boundary, and/or with erroneous trailing characters. */ if (ch == Pad64) { /* We got a pad char. */ ch = *src++; /* Skip it, get next. */ switch (state) { case 0: /* Invalid = in first position */ case 1: /* Invalid = in second position */ return (-1); case 2: /* Valid, means one byte of info */ /* Skip any number of spaces. */ for ((void)NULL; ch != '\0'; ch = *src++) if (b64rmap[ch] != b64rmap_space) break; /* Make sure there is another trailing = sign. */ if (ch != Pad64) return (-1); ch = *src++; /* Skip the = */ /* Fall through to "single trailing =" case. */ /* FALLTHROUGH */ case 3: /* Valid, means two bytes of info */ /* * We know this char is an =. Is there anything but * whitespace after it? */ for ((void)NULL; ch != '\0'; ch = *src++) if (b64rmap[ch] != b64rmap_space) return (-1); default: break; } } else { /* * We ended by seeing the end of the string. Make sure we * have no partial bytes lying around. */ if (state != 0) return (-1); } return (tarindex); } static int b64_pton(char const *src, uint8_t *target, size_t targsize) { if (!b64rmap_initialized) b64_initialize_rmap (); if (target) return b64_pton_do (src, target, targsize); else return b64_pton_len (src); } mongodb-1.1.5/src/libbson/src/bson/bcon.c0000664000175000017500000006424712673034026020057 0ustar jmikolajmikola/* * @file bcon.c * @brief BCON (BSON C Object Notation) Implementation */ /* Copyright 2009-2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include "bcon.h" /* These stack manipulation macros are used to manage append recursion in * bcon_append_ctx_va(). They take care of some awkward dereference rules (the * real bson object isn't in the stack, but accessed by pointer) and add in run * time asserts to make sure we don't blow the stack in either direction */ #define STACK_ELE(_delta, _name) (ctx->stack[(_delta) + ctx->n]._name) #define STACK_BSON(_delta) ( \ ((_delta) + ctx->n) == 0 \ ? bson \ : &STACK_ELE (_delta, bson) \ ) #define STACK_ITER(_delta) ( \ ((_delta) + ctx->n) == 0 \ ? &root_iter \ : &STACK_ELE (_delta, iter) \ ) #define STACK_BSON_PARENT STACK_BSON (-1) #define STACK_BSON_CHILD STACK_BSON (0) #define STACK_ITER_PARENT STACK_ITER (-1) #define STACK_ITER_CHILD STACK_ITER (0) #define STACK_I STACK_ELE (0, i) #define STACK_IS_ARRAY STACK_ELE (0, is_array) #define STACK_PUSH_ARRAY(statement) \ do { \ assert (ctx->n < (BCON_STACK_MAX - 1)); \ ctx->n++; \ STACK_I = 0; \ STACK_IS_ARRAY = 1; \ statement; \ } while (0) #define STACK_PUSH_DOC(statement) \ do { \ assert (ctx->n < (BCON_STACK_MAX - 1)); \ ctx->n++; \ STACK_IS_ARRAY = 0; \ statement; \ } while (0) #define STACK_POP_ARRAY(statement) \ do { \ assert (STACK_IS_ARRAY); \ assert (ctx->n != 0); \ statement; \ ctx->n--; \ } while (0) #define STACK_POP_DOC(statement) \ do { \ assert (!STACK_IS_ARRAY); \ assert (ctx->n != 0); \ statement; \ ctx->n--; \ } while (0) /* This is a landing pad union for all of the types we can process with bcon. * We need actual storage for this to capture the return value of va_arg, which * takes multiple calls to get everything we need for some complex types */ typedef union bcon_append { char *UTF8; double DOUBLE; bson_t *DOCUMENT; bson_t *ARRAY; bson_t *BCON; struct { bson_subtype_t subtype; uint8_t *binary; uint32_t length; } BIN; bson_oid_t *OID; bool BOOL; int64_t DATE_TIME; struct { char *regex; char *flags; } REGEX; struct { char *collection; bson_oid_t *oid; } DBPOINTER; const char *CODE; char *SYMBOL; struct { const char *js; bson_t *scope; } CODEWSCOPE; int32_t INT32; struct { uint32_t timestamp; uint32_t increment; } TIMESTAMP; int64_t INT64; const bson_iter_t *ITER; } bcon_append_t; /* same as bcon_append_t. Some extra symbols and varying types that handle the * differences between bson_append and bson_iter */ typedef union bcon_extract { bson_type_t TYPE; bson_iter_t *ITER; const char *key; const char **UTF8; double *DOUBLE; bson_t *DOCUMENT; bson_t *ARRAY; struct { bson_subtype_t *subtype; const uint8_t **binary; uint32_t *length; } BIN; const bson_oid_t **OID; bool *BOOL; int64_t *DATE_TIME; struct { const char **regex; const char **flags; } REGEX; struct { const char **collection; const bson_oid_t **oid; } DBPOINTER; const char **CODE; const char **SYMBOL; struct { const char **js; bson_t *scope; } CODEWSCOPE; int32_t *INT32; struct { uint32_t *timestamp; uint32_t *increment; } TIMESTAMP; int64_t *INT64; } bcon_extract_t; static const char *gBconMagic = "BCON_MAGIC"; static const char *gBconeMagic = "BCONE_MAGIC"; const char * bson_bcon_magic (void) { return gBconMagic; } const char * bson_bcone_magic (void) { return gBconeMagic; } static void _noop (void) { } /* appends val to the passed bson object. Meant to be a super simple dispatch * table */ static void _bcon_append_single (bson_t *bson, bcon_type_t type, const char *key, bcon_append_t *val) { switch ((int)type) { case BCON_TYPE_UTF8: bson_append_utf8 (bson, key, -1, val->UTF8, -1); break; case BCON_TYPE_DOUBLE: bson_append_double (bson, key, -1, val->DOUBLE); break; case BCON_TYPE_BIN: { bson_append_binary (bson, key, -1, val->BIN.subtype, val->BIN.binary, val->BIN.length); break; } case BCON_TYPE_UNDEFINED: bson_append_undefined (bson, key, -1); break; case BCON_TYPE_OID: bson_append_oid (bson, key, -1, val->OID); break; case BCON_TYPE_BOOL: bson_append_bool (bson, key, -1, (bool)val->BOOL); break; case BCON_TYPE_DATE_TIME: bson_append_date_time (bson, key, -1, val->DATE_TIME); break; case BCON_TYPE_NULL: bson_append_null (bson, key, -1); break; case BCON_TYPE_REGEX: { bson_append_regex (bson, key, -1, val->REGEX.regex, val->REGEX.flags); break; } case BCON_TYPE_DBPOINTER: { bson_append_dbpointer (bson, key, -1, val->DBPOINTER.collection, val->DBPOINTER.oid); break; } case BCON_TYPE_CODE: bson_append_code (bson, key, -1, val->CODE); break; case BCON_TYPE_SYMBOL: bson_append_symbol (bson, key, -1, val->SYMBOL, -1); break; case BCON_TYPE_CODEWSCOPE: bson_append_code_with_scope (bson, key, -1, val->CODEWSCOPE.js, val->CODEWSCOPE.scope); break; case BCON_TYPE_INT32: bson_append_int32 (bson, key, -1, val->INT32); break; case BCON_TYPE_TIMESTAMP: { bson_append_timestamp (bson, key, -1, val->TIMESTAMP.timestamp, val->TIMESTAMP.increment); break; } case BCON_TYPE_INT64: bson_append_int64 (bson, key, -1, val->INT64); break; case BCON_TYPE_MAXKEY: bson_append_maxkey (bson, key, -1); break; case BCON_TYPE_MINKEY: bson_append_minkey (bson, key, -1); break; case BCON_TYPE_ARRAY: { bson_append_array (bson, key, -1, val->ARRAY); break; } case BCON_TYPE_DOCUMENT: { bson_append_document (bson, key, -1, val->DOCUMENT); break; } case BCON_TYPE_ITER: bson_append_iter (bson, key, -1, val->ITER); break; default: assert (0); break; } } #define CHECK_TYPE(_type) \ do { \ if (bson_iter_type (iter) != (_type)) { return false; } \ } while (0) /* extracts the value under the iterator and writes it to val. returns false * if the iterator type doesn't match the token type. * * There are two magic tokens: * * BCONE_SKIP - * Let's us verify that a key has a type, without caring about its value. * This allows for wider declarative BSON verification * * BCONE_ITER - * Returns the underlying iterator. This could allow for more complicated, * procedural verification (if a parameter could have multiple types). * */ static bool _bcon_extract_single (const bson_iter_t *iter, bcon_type_t type, bcon_extract_t *val) { switch ((int)type) { case BCON_TYPE_UTF8: CHECK_TYPE (BSON_TYPE_UTF8); *val->UTF8 = bson_iter_utf8 (iter, NULL); break; case BCON_TYPE_DOUBLE: CHECK_TYPE (BSON_TYPE_DOUBLE); *val->DOUBLE = bson_iter_double (iter); break; case BCON_TYPE_BIN: CHECK_TYPE (BSON_TYPE_BINARY); bson_iter_binary (iter, val->BIN.subtype, val->BIN.length, val->BIN.binary); break; case BCON_TYPE_UNDEFINED: CHECK_TYPE (BSON_TYPE_UNDEFINED); break; case BCON_TYPE_OID: CHECK_TYPE (BSON_TYPE_OID); *val->OID = bson_iter_oid (iter); break; case BCON_TYPE_BOOL: CHECK_TYPE (BSON_TYPE_BOOL); *val->BOOL = bson_iter_bool (iter); break; case BCON_TYPE_DATE_TIME: CHECK_TYPE (BSON_TYPE_DATE_TIME); *val->DATE_TIME = bson_iter_date_time (iter); break; case BCON_TYPE_NULL: CHECK_TYPE (BSON_TYPE_NULL); break; case BCON_TYPE_REGEX: CHECK_TYPE (BSON_TYPE_REGEX); *val->REGEX.regex = bson_iter_regex (iter, val->REGEX.flags); break; case BCON_TYPE_DBPOINTER: CHECK_TYPE (BSON_TYPE_DBPOINTER); bson_iter_dbpointer (iter, NULL, val->DBPOINTER.collection, val->DBPOINTER.oid); break; case BCON_TYPE_CODE: CHECK_TYPE (BSON_TYPE_CODE); *val->CODE = bson_iter_code (iter, NULL); break; case BCON_TYPE_SYMBOL: CHECK_TYPE (BSON_TYPE_SYMBOL); *val->SYMBOL = bson_iter_symbol (iter, NULL); break; case BCON_TYPE_CODEWSCOPE: { const uint8_t *buf; uint32_t len; CHECK_TYPE (BSON_TYPE_CODEWSCOPE); *val->CODEWSCOPE.js = bson_iter_codewscope (iter, NULL, &len, &buf); bson_init_static (val->CODEWSCOPE.scope, buf, len); break; } case BCON_TYPE_INT32: CHECK_TYPE (BSON_TYPE_INT32); *val->INT32 = bson_iter_int32 (iter); break; case BCON_TYPE_TIMESTAMP: CHECK_TYPE (BSON_TYPE_TIMESTAMP); bson_iter_timestamp (iter, val->TIMESTAMP.timestamp, val->TIMESTAMP.increment); break; case BCON_TYPE_INT64: CHECK_TYPE (BSON_TYPE_INT64); *val->INT64 = bson_iter_int64 (iter); break; case BCON_TYPE_MAXKEY: CHECK_TYPE (BSON_TYPE_MAXKEY); break; case BCON_TYPE_MINKEY: CHECK_TYPE (BSON_TYPE_MINKEY); break; case BCON_TYPE_ARRAY: { const uint8_t *buf; uint32_t len; CHECK_TYPE (BSON_TYPE_ARRAY); bson_iter_array (iter, &len, &buf); bson_init_static (val->ARRAY, buf, len); break; } case BCON_TYPE_DOCUMENT: { const uint8_t *buf; uint32_t len; CHECK_TYPE (BSON_TYPE_DOCUMENT); bson_iter_document (iter, &len, &buf); bson_init_static (val->DOCUMENT, buf, len); break; } case BCON_TYPE_SKIP: CHECK_TYPE (val->TYPE); break; case BCON_TYPE_ITER: memcpy (val->ITER, iter, sizeof *iter); break; default: assert (0); break; } return true; } /* Consumes ap, storing output values into u and returning the type of the * captured token. * * The basic workflow goes like this: * * 1. Look at the current arg. It will be a char * * a. If it's a NULL, we're done processing. * b. If it's BCON_MAGIC (a symbol with storage in this module) * I. The next token is the type * II. The type specifies how many args to eat and their types * c. Otherwise it's either recursion related or a raw string * I. If the first byte is '{', '}', '[', or ']' pass back an * appropriate recursion token * II. If not, just call it a UTF8 token and pass that back */ static bcon_type_t _bcon_append_tokenize (va_list *ap, bcon_append_t *u) { char *mark; bcon_type_t type; mark = va_arg (*ap, char *); assert (mark != BCONE_MAGIC); if (mark == NULL) { type = BCON_TYPE_END; } else if (mark == BCON_MAGIC) { type = va_arg (*ap, bcon_type_t); switch ((int)type) { case BCON_TYPE_UTF8: u->UTF8 = va_arg (*ap, char *); break; case BCON_TYPE_DOUBLE: u->DOUBLE = va_arg (*ap, double); break; case BCON_TYPE_DOCUMENT: u->DOCUMENT = va_arg (*ap, bson_t *); break; case BCON_TYPE_ARRAY: u->ARRAY = va_arg (*ap, bson_t *); break; case BCON_TYPE_BIN: u->BIN.subtype = va_arg (*ap, bson_subtype_t); u->BIN.binary = va_arg (*ap, uint8_t *); u->BIN.length = va_arg (*ap, uint32_t); break; case BCON_TYPE_UNDEFINED: break; case BCON_TYPE_OID: u->OID = va_arg (*ap, bson_oid_t *); break; case BCON_TYPE_BOOL: u->BOOL = va_arg (*ap, int); break; case BCON_TYPE_DATE_TIME: u->DATE_TIME = va_arg (*ap, int64_t); break; case BCON_TYPE_NULL: break; case BCON_TYPE_REGEX: u->REGEX.regex = va_arg (*ap, char *); u->REGEX.flags = va_arg (*ap, char *); break; case BCON_TYPE_DBPOINTER: u->DBPOINTER.collection = va_arg (*ap, char *); u->DBPOINTER.oid = va_arg (*ap, bson_oid_t *); break; case BCON_TYPE_CODE: u->CODE = va_arg (*ap, char *); break; case BCON_TYPE_SYMBOL: u->SYMBOL = va_arg (*ap, char *); break; case BCON_TYPE_CODEWSCOPE: u->CODEWSCOPE.js = va_arg (*ap, char *); u->CODEWSCOPE.scope = va_arg (*ap, bson_t *); break; case BCON_TYPE_INT32: u->INT32 = va_arg (*ap, int32_t); break; case BCON_TYPE_TIMESTAMP: u->TIMESTAMP.timestamp = va_arg (*ap, uint32_t); u->TIMESTAMP.increment = va_arg (*ap, uint32_t); break; case BCON_TYPE_INT64: u->INT64 = va_arg (*ap, int64_t); break; case BCON_TYPE_MAXKEY: break; case BCON_TYPE_MINKEY: break; case BCON_TYPE_BCON: u->BCON = va_arg (*ap, bson_t *); break; case BCON_TYPE_ITER: u->ITER = va_arg (*ap, const bson_iter_t *); break; default: assert (0); break; } } else { switch (mark[0]) { case '{': type = BCON_TYPE_DOC_START; break; case '}': type = BCON_TYPE_DOC_END; break; case '[': type = BCON_TYPE_ARRAY_START; break; case ']': type = BCON_TYPE_ARRAY_END; break; default: type = BCON_TYPE_UTF8; u->UTF8 = mark; break; } } return type; } /* Consumes ap, storing output values into u and returning the type of the * captured token. * * The basic workflow goes like this: * * 1. Look at the current arg. It will be a char * * a. If it's a NULL, we're done processing. * b. If it's BCONE_MAGIC (a symbol with storage in this module) * I. The next token is the type * II. The type specifies how many args to eat and their types * c. Otherwise it's either recursion related or a raw string * I. If the first byte is '{', '}', '[', or ']' pass back an * appropriate recursion token * II. If not, just call it a UTF8 token and pass that back */ static bcon_type_t _bcon_extract_tokenize (va_list *ap, bcon_extract_t *u) { char *mark; bcon_type_t type; mark = va_arg (*ap, char *); assert (mark != BCON_MAGIC); if (mark == NULL) { type = BCON_TYPE_END; } else if (mark == BCONE_MAGIC) { type = va_arg (*ap, bcon_type_t); switch ((int)type) { case BCON_TYPE_UTF8: u->UTF8 = va_arg (*ap, const char **); break; case BCON_TYPE_DOUBLE: u->DOUBLE = va_arg (*ap, double *); break; case BCON_TYPE_DOCUMENT: u->DOCUMENT = va_arg (*ap, bson_t *); break; case BCON_TYPE_ARRAY: u->ARRAY = va_arg (*ap, bson_t *); break; case BCON_TYPE_BIN: u->BIN.subtype = va_arg (*ap, bson_subtype_t *); u->BIN.binary = va_arg (*ap, const uint8_t * *); u->BIN.length = va_arg (*ap, uint32_t *); break; case BCON_TYPE_UNDEFINED: break; case BCON_TYPE_OID: u->OID = va_arg (*ap, const bson_oid_t * *); break; case BCON_TYPE_BOOL: u->BOOL = va_arg (*ap, bool *); break; case BCON_TYPE_DATE_TIME: u->DATE_TIME = va_arg (*ap, int64_t *); break; case BCON_TYPE_NULL: break; case BCON_TYPE_REGEX: u->REGEX.regex = va_arg (*ap, const char **); u->REGEX.flags = va_arg (*ap, const char **); break; case BCON_TYPE_DBPOINTER: u->DBPOINTER.collection = va_arg (*ap, const char **); u->DBPOINTER.oid = va_arg (*ap, const bson_oid_t * *); break; case BCON_TYPE_CODE: u->CODE = va_arg (*ap, const char **); break; case BCON_TYPE_SYMBOL: u->SYMBOL = va_arg (*ap, const char **); break; case BCON_TYPE_CODEWSCOPE: u->CODEWSCOPE.js = va_arg (*ap, const char **); u->CODEWSCOPE.scope = va_arg (*ap, bson_t *); break; case BCON_TYPE_INT32: u->INT32 = va_arg (*ap, int32_t *); break; case BCON_TYPE_TIMESTAMP: u->TIMESTAMP.timestamp = va_arg (*ap, uint32_t *); u->TIMESTAMP.increment = va_arg (*ap, uint32_t *); break; case BCON_TYPE_INT64: u->INT64 = va_arg (*ap, int64_t *); break; case BCON_TYPE_MAXKEY: break; case BCON_TYPE_MINKEY: break; case BCON_TYPE_SKIP: u->TYPE = va_arg (*ap, bson_type_t); break; case BCON_TYPE_ITER: u->ITER = va_arg (*ap, bson_iter_t *); break; default: assert (0); break; } } else { switch (mark[0]) { case '{': type = BCON_TYPE_DOC_START; break; case '}': type = BCON_TYPE_DOC_END; break; case '[': type = BCON_TYPE_ARRAY_START; break; case ']': type = BCON_TYPE_ARRAY_END; break; default: type = BCON_TYPE_RAW; u->key = mark; break; } } return type; } /* This trivial utility function is useful for concatenating a bson object onto * the end of another, ignoring the keys from the source bson object and * continuing to use and increment the keys from the source. It's only useful * when called from bcon_append_ctx_va */ static void _bson_concat_array (bson_t *dest, const bson_t *src, bcon_append_ctx_t *ctx) { bson_iter_t iter; const char *key; char i_str[16]; bool r; r = bson_iter_init (&iter, src); if (!r) { fprintf (stderr, "Invalid BSON document, possible memory coruption.\n"); return; } STACK_I--; while (bson_iter_next (&iter)) { bson_uint32_to_string (STACK_I, &key, i_str, sizeof i_str); STACK_I++; bson_append_iter (dest, key, -1, &iter); } } /* Append_ctx_va consumes the va_list until NULL is found, appending into bson * as tokens are found. It can receive or return an in-progress bson object * via the ctx param. It can also operate on the middle of a va_list, and so * can be wrapped inside of another varargs function. * * Note that passing in a va_list that isn't perferectly formatted for BCON * ingestion will almost certainly result in undefined behavior * * The workflow relies on the passed ctx object, which holds a stack of bson * objects, along with metadata (if the emedded layer is an array, and which * element it is on if so). We iterate, generating tokens from the va_list, * until we reach an END token. If any errors occur, we just blow up (the * var_args stuff is already incredibly fragile to mistakes, and we have no way * of introspecting, so just don't screw it up). * * There are also a few STACK_* macros in here which manimpulate ctx that are * defined up top. * */ void bcon_append_ctx_va (bson_t *bson, bcon_append_ctx_t *ctx, va_list *ap) { bcon_type_t type; const char *key; char i_str[16]; bcon_append_t u = { 0 }; while (1) { if (STACK_IS_ARRAY) { bson_uint32_to_string (STACK_I, &key, i_str, sizeof i_str); STACK_I++; } else { type = _bcon_append_tokenize (ap, &u); if (type == BCON_TYPE_END) { return; } if (type == BCON_TYPE_DOC_END) { STACK_POP_DOC (bson_append_document_end (STACK_BSON_PARENT, STACK_BSON_CHILD)); continue; } if (type == BCON_TYPE_BCON) { bson_concat (STACK_BSON_CHILD, u.BCON); continue; } assert (type == BCON_TYPE_UTF8); key = u.UTF8; } type = _bcon_append_tokenize (ap, &u); assert (type != BCON_TYPE_END); switch ((int)type) { case BCON_TYPE_BCON: assert (STACK_IS_ARRAY); _bson_concat_array (STACK_BSON_CHILD, u.BCON, ctx); break; case BCON_TYPE_DOC_START: STACK_PUSH_DOC (bson_append_document_begin (STACK_BSON_PARENT, key, -1, STACK_BSON_CHILD)); break; case BCON_TYPE_DOC_END: STACK_POP_DOC (bson_append_document_end (STACK_BSON_PARENT, STACK_BSON_CHILD)); break; case BCON_TYPE_ARRAY_START: STACK_PUSH_ARRAY (bson_append_array_begin (STACK_BSON_PARENT, key, -1, STACK_BSON_CHILD)); break; case BCON_TYPE_ARRAY_END: STACK_POP_ARRAY (bson_append_array_end (STACK_BSON_PARENT, STACK_BSON_CHILD)); break; default: _bcon_append_single (STACK_BSON_CHILD, type, key, &u); break; } } } /* extract_ctx_va consumes the va_list until NULL is found, extracting values * as tokens are found. It can receive or return an in-progress bson object * via the ctx param. It can also operate on the middle of a va_list, and so * can be wrapped inside of another varargs function. * * Note that passing in a va_list that isn't perferectly formatted for BCON * ingestion will almost certainly result in undefined behavior * * The workflow relies on the passed ctx object, which holds a stack of iterator * objects, along with metadata (if the emedded layer is an array, and which * element it is on if so). We iterate, generating tokens from the va_list, * until we reach an END token. If any errors occur, we just blow up (the * var_args stuff is already incredibly fragile to mistakes, and we have no way * of introspecting, so just don't screw it up). * * There are also a few STACK_* macros in here which manimpulate ctx that are * defined up top. * * The function returns true if all tokens could be successfully matched, false * otherwise. * */ bool bcon_extract_ctx_va (bson_t *bson, bcon_extract_ctx_t *ctx, va_list *ap) { bcon_type_t type; const char *key; bson_iter_t root_iter; bson_iter_t current_iter; char i_str[16]; bcon_extract_t u = { 0 }; bson_iter_init (&root_iter, bson); while (1) { if (STACK_IS_ARRAY) { bson_uint32_to_string (STACK_I, &key, i_str, sizeof i_str); STACK_I++; } else { type = _bcon_extract_tokenize (ap, &u); if (type == BCON_TYPE_END) { return true; } if (type == BCON_TYPE_DOC_END) { STACK_POP_DOC (_noop ()); continue; } assert (type == BCON_TYPE_RAW); key = u.key; } type = _bcon_extract_tokenize (ap, &u); assert (type != BCON_TYPE_END); if (type == BCON_TYPE_DOC_END) { STACK_POP_DOC (_noop ()); } else if (type == BCON_TYPE_ARRAY_END) { STACK_POP_ARRAY (_noop ()); } else { memcpy (¤t_iter, STACK_ITER_CHILD, sizeof current_iter); if (!bson_iter_find (¤t_iter, key)) { return false; } switch ((int)type) { case BCON_TYPE_DOC_START: if (bson_iter_type (¤t_iter) != BSON_TYPE_DOCUMENT) { return false; } STACK_PUSH_DOC (bson_iter_recurse (¤t_iter, STACK_ITER_CHILD)); break; case BCON_TYPE_ARRAY_START: if (bson_iter_type (¤t_iter) != BSON_TYPE_ARRAY) { return false; } STACK_PUSH_ARRAY (bson_iter_recurse (¤t_iter, STACK_ITER_CHILD)); break; default: if (!_bcon_extract_single (¤t_iter, type, &u)) { return false; } break; } } } } void bcon_extract_ctx_init (bcon_extract_ctx_t *ctx) { ctx->n = 0; ctx->stack[0].is_array = false; } bool bcon_extract (bson_t *bson, ...) { va_list ap; bcon_extract_ctx_t ctx; bool r; bcon_extract_ctx_init (&ctx); va_start (ap, bson); r = bcon_extract_ctx_va (bson, &ctx, &ap); va_end (ap); return r; } void bcon_append (bson_t *bson, ...) { va_list ap; bcon_append_ctx_t ctx; bcon_append_ctx_init (&ctx); va_start (ap, bson); bcon_append_ctx_va (bson, &ctx, &ap); va_end (ap); } void bcon_append_ctx (bson_t *bson, bcon_append_ctx_t *ctx, ...) { va_list ap; va_start (ap, ctx); bcon_append_ctx_va (bson, ctx, &ap); va_end (ap); } void bcon_extract_ctx (bson_t *bson, bcon_extract_ctx_t *ctx, ...) { va_list ap; va_start (ap, ctx); bcon_extract_ctx_va (bson, ctx, &ap); va_end (ap); } void bcon_append_ctx_init (bcon_append_ctx_t *ctx) { ctx->n = 0; ctx->stack[0].is_array = 0; } bson_t * bcon_new (void *unused, ...) { va_list ap; bcon_append_ctx_t ctx; bson_t *bson; bcon_append_ctx_init (&ctx); bson = bson_new (); va_start (ap, unused); bcon_append_ctx_va (bson, &ctx, &ap); va_end (ap); return bson; } mongodb-1.1.5/src/libbson/src/bson/bcon.h0000664000175000017500000002370212673034026020053 0ustar jmikolajmikola/* * @file bcon.h * @brief BCON (BSON C Object Notation) Declarations */ /* Copyright 2009-2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef BCON_H_ #define BCON_H_ #include BSON_BEGIN_DECLS #define BCON_STACK_MAX 100 #define BCON_ENSURE_DECLARE(fun, type) \ static BSON_INLINE type bcon_ensure_##fun (type _t) { return _t; } #define BCON_ENSURE(fun, val) \ bcon_ensure_##fun (val) #define BCON_ENSURE_STORAGE(fun, val) \ bcon_ensure_##fun (&(val)) BCON_ENSURE_DECLARE (const_char_ptr, const char *) BCON_ENSURE_DECLARE (const_char_ptr_ptr, const char **) BCON_ENSURE_DECLARE (double, double) BCON_ENSURE_DECLARE (double_ptr, double *) BCON_ENSURE_DECLARE (const_bson_ptr, const bson_t *) BCON_ENSURE_DECLARE (bson_ptr, bson_t *) BCON_ENSURE_DECLARE (subtype, bson_subtype_t) BCON_ENSURE_DECLARE (subtype_ptr, bson_subtype_t *) BCON_ENSURE_DECLARE (const_uint8_ptr, const uint8_t *) BCON_ENSURE_DECLARE (const_uint8_ptr_ptr, const uint8_t **) BCON_ENSURE_DECLARE (uint32, uint32_t) BCON_ENSURE_DECLARE (uint32_ptr, uint32_t *) BCON_ENSURE_DECLARE (const_oid_ptr, const bson_oid_t *) BCON_ENSURE_DECLARE (const_oid_ptr_ptr, const bson_oid_t **) BCON_ENSURE_DECLARE (int32, int32_t) BCON_ENSURE_DECLARE (int32_ptr, int32_t *) BCON_ENSURE_DECLARE (int64, int64_t) BCON_ENSURE_DECLARE (int64_ptr, int64_t *) BCON_ENSURE_DECLARE (bool, bool) BCON_ENSURE_DECLARE (bool_ptr, bool *) BCON_ENSURE_DECLARE (bson_type, bson_type_t) BCON_ENSURE_DECLARE (bson_iter_ptr, bson_iter_t *) BCON_ENSURE_DECLARE (const_bson_iter_ptr, const bson_iter_t *) #define BCON_UTF8(_val) \ BCON_MAGIC, BCON_TYPE_UTF8, BCON_ENSURE (const_char_ptr, (_val)) #define BCON_DOUBLE(_val) \ BCON_MAGIC, BCON_TYPE_DOUBLE, BCON_ENSURE (double, (_val)) #define BCON_DOCUMENT(_val) \ BCON_MAGIC, BCON_TYPE_DOCUMENT, BCON_ENSURE (const_bson_ptr, (_val)) #define BCON_ARRAY(_val) \ BCON_MAGIC, BCON_TYPE_ARRAY, BCON_ENSURE (const_bson_ptr, (_val)) #define BCON_BIN(_subtype, _binary, _length) \ BCON_MAGIC, BCON_TYPE_BIN, \ BCON_ENSURE (subtype, (_subtype)), \ BCON_ENSURE (const_uint8_ptr, (_binary)), \ BCON_ENSURE (uint32, (_length)) #define BCON_UNDEFINED BCON_MAGIC, BCON_TYPE_UNDEFINED #define BCON_OID(_val) \ BCON_MAGIC, BCON_TYPE_OID, BCON_ENSURE (const_oid_ptr, (_val)) #define BCON_BOOL(_val) \ BCON_MAGIC, BCON_TYPE_BOOL, BCON_ENSURE (bool, (_val)) #define BCON_DATE_TIME(_val) \ BCON_MAGIC, BCON_TYPE_DATE_TIME, BCON_ENSURE (int64, (_val)) #define BCON_NULL BCON_MAGIC, BCON_TYPE_NULL #define BCON_REGEX(_regex, _flags) \ BCON_MAGIC, BCON_TYPE_REGEX, \ BCON_ENSURE (const_char_ptr, (_regex)), \ BCON_ENSURE (const_char_ptr, (_flags)) #define BCON_DBPOINTER(_collection, _oid) \ BCON_MAGIC, BCON_TYPE_DBPOINTER, \ BCON_ENSURE (const_char_ptr, (_collection)), \ BCON_ENSURE (const_oid_ptr, (_oid)) #define BCON_CODE(_val) \ BCON_MAGIC, BCON_TYPE_CODE, BCON_ENSURE (const_char_ptr, (_val)) #define BCON_SYMBOL(_val) \ BCON_MAGIC, BCON_TYPE_SYMBOL, BCON_ENSURE (const_char_ptr, (_val)) #define BCON_CODEWSCOPE(_js, _scope) \ BCON_MAGIC, BCON_TYPE_CODEWSCOPE, \ BCON_ENSURE (const_char_ptr, (_js)), \ BCON_ENSURE (const_bson_ptr, (_scope)) #define BCON_INT32(_val) \ BCON_MAGIC, BCON_TYPE_INT32, BCON_ENSURE (int32, (_val)) #define BCON_TIMESTAMP(_timestamp, _increment) \ BCON_MAGIC, BCON_TYPE_TIMESTAMP, \ BCON_ENSURE (int32, (_timestamp)), \ BCON_ENSURE (int32, (_increment)) #define BCON_INT64(_val) \ BCON_MAGIC, BCON_TYPE_INT64, BCON_ENSURE (int64, (_val)) #define BCON_MAXKEY BCON_MAGIC, BCON_TYPE_MAXKEY #define BCON_MINKEY BCON_MAGIC, BCON_TYPE_MINKEY #define BCON(_val) \ BCON_MAGIC, BCON_TYPE_BCON, BCON_ENSURE (const_bson_ptr, (_val)) #define BCON_ITER(_val) \ BCON_MAGIC, BCON_TYPE_ITER, BCON_ENSURE (const_bson_iter_ptr, (_val)) #define BCONE_UTF8(_val) BCONE_MAGIC, BCON_TYPE_UTF8, \ BCON_ENSURE_STORAGE (const_char_ptr_ptr, (_val)) #define BCONE_DOUBLE(_val) BCONE_MAGIC, BCON_TYPE_DOUBLE, \ BCON_ENSURE_STORAGE (double_ptr, (_val)) #define BCONE_DOCUMENT(_val) BCONE_MAGIC, BCON_TYPE_DOCUMENT, \ BCON_ENSURE_STORAGE (bson_ptr, (_val)) #define BCONE_ARRAY(_val) BCONE_MAGIC, BCON_TYPE_ARRAY, \ BCON_ENSURE_STORAGE (bson_ptr, (_val)) #define BCONE_BIN(subtype, binary, length) \ BCONE_MAGIC, BCON_TYPE_BIN, \ BCON_ENSURE_STORAGE (subtype_ptr, (subtype)), \ BCON_ENSURE_STORAGE (const_uint8_ptr_ptr, (binary)), \ BCON_ENSURE_STORAGE (uint32_ptr, (length)) #define BCONE_UNDEFINED BCONE_MAGIC, BCON_TYPE_UNDEFINED #define BCONE_OID(_val) BCONE_MAGIC, BCON_TYPE_OID, \ BCON_ENSURE_STORAGE (const_oid_ptr_ptr, (_val)) #define BCONE_BOOL(_val) BCONE_MAGIC, BCON_TYPE_BOOL, \ BCON_ENSURE_STORAGE (bool_ptr, (_val)) #define BCONE_DATE_TIME(_val) BCONE_MAGIC, BCON_TYPE_DATE_TIME, \ BCON_ENSURE_STORAGE (int64_ptr, (_val)) #define BCONE_NULL BCONE_MAGIC, BCON_TYPE_NULL #define BCONE_REGEX(_regex, _flags) \ BCONE_MAGIC, BCON_TYPE_REGEX, \ BCON_ENSURE_STORAGE (const_char_ptr_ptr, (_regex)), \ BCON_ENSURE_STORAGE (const_char_ptr_ptr, (_flags)) #define BCONE_DBPOINTER(_collection, _oid) \ BCONE_MAGIC, BCON_TYPE_DBPOINTER, \ BCON_ENSURE_STORAGE (const_char_ptr_ptr, (_collection)), \ BCON_ENSURE_STORAGE (const_oid_ptr_ptr, (_oid)) #define BCONE_CODE(_val) BCONE_MAGIC, BCON_TYPE_CODE, \ BCON_ENSURE_STORAGE (const_char_ptr_ptr, (_val)) #define BCONE_SYMBOL(_val) BCONE_MAGIC, BCON_TYPE_SYMBOL, \ BCON_ENSURE_STORAGE (const_char_ptr_ptr, (_val)) #define BCONE_CODEWSCOPE(_js, _scope) \ BCONE_MAGIC, BCON_TYPE_CODEWSCOPE, \ BCON_ENSURE_STORAGE (const_char_ptr_ptr, (_js)), \ BCON_ENSURE_STORAGE (bson_ptr, (_scope)) #define BCONE_INT32(_val) BCONE_MAGIC, BCON_TYPE_INT32, \ BCON_ENSURE_STORAGE (int32_ptr, (_val)) #define BCONE_TIMESTAMP(_timestamp, _increment) \ BCONE_MAGIC, BCON_TYPE_TIMESTAMP, \ BCON_ENSURE_STORAGE (int32_ptr, (_timestamp)), \ BCON_ENSURE_STORAGE (int32_ptr, (_increment)) #define BCONE_INT64(_val) BCONE_MAGIC, BCON_TYPE_INT64, \ BCON_ENSURE_STORAGE (int64_ptr, (_val)) #define BCONE_MAXKEY BCONE_MAGIC, BCON_TYPE_MAXKEY #define BCONE_MINKEY BCONE_MAGIC, BCON_TYPE_MINKEY #define BCONE_SKIP(_val) BCONE_MAGIC, BCON_TYPE_SKIP, \ BCON_ENSURE (bson_type, (_val)) #define BCONE_ITER(_val) BCONE_MAGIC, BCON_TYPE_ITER, \ BCON_ENSURE_STORAGE (bson_iter_ptr, (_val)) #define BCON_MAGIC bson_bcon_magic() #define BCONE_MAGIC bson_bcone_magic() typedef enum { BCON_TYPE_UTF8, BCON_TYPE_DOUBLE, BCON_TYPE_DOCUMENT, BCON_TYPE_ARRAY, BCON_TYPE_BIN, BCON_TYPE_UNDEFINED, BCON_TYPE_OID, BCON_TYPE_BOOL, BCON_TYPE_DATE_TIME, BCON_TYPE_NULL, BCON_TYPE_REGEX, BCON_TYPE_DBPOINTER, BCON_TYPE_CODE, BCON_TYPE_SYMBOL, BCON_TYPE_CODEWSCOPE, BCON_TYPE_INT32, BCON_TYPE_TIMESTAMP, BCON_TYPE_INT64, BCON_TYPE_MAXKEY, BCON_TYPE_MINKEY, BCON_TYPE_BCON, BCON_TYPE_ARRAY_START, BCON_TYPE_ARRAY_END, BCON_TYPE_DOC_START, BCON_TYPE_DOC_END, BCON_TYPE_END, BCON_TYPE_RAW, BCON_TYPE_SKIP, BCON_TYPE_ITER, BCON_TYPE_ERROR, } bcon_type_t; typedef struct bcon_append_ctx_frame { int i; bool is_array; bson_t bson; } bcon_append_ctx_frame_t; typedef struct bcon_extract_ctx_frame { int i; bool is_array; bson_iter_t iter; } bcon_extract_ctx_frame_t; typedef struct _bcon_append_ctx_t { bcon_append_ctx_frame_t stack[BCON_STACK_MAX]; int n; } bcon_append_ctx_t; typedef struct _bcon_extract_ctx_t { bcon_extract_ctx_frame_t stack[BCON_STACK_MAX]; int n; } bcon_extract_ctx_t; void bcon_append (bson_t *bson, ...) BSON_GNUC_NULL_TERMINATED; void bcon_append_ctx (bson_t *bson, bcon_append_ctx_t *ctx, ...) BSON_GNUC_NULL_TERMINATED; void bcon_append_ctx_va (bson_t *bson, bcon_append_ctx_t *ctx, va_list *va); void bcon_append_ctx_init (bcon_append_ctx_t *ctx); void bcon_extract_ctx_init (bcon_extract_ctx_t *ctx); void bcon_extract_ctx (bson_t *bson, bcon_extract_ctx_t *ctx, ...) BSON_GNUC_NULL_TERMINATED; bool bcon_extract_ctx_va (bson_t *bson, bcon_extract_ctx_t *ctx, va_list *ap); bool bcon_extract (bson_t *bson, ...) BSON_GNUC_NULL_TERMINATED; bool bcon_extract_va (bson_t *bson, bcon_extract_ctx_t *ctx, ...) BSON_GNUC_NULL_TERMINATED; bson_t * bcon_new (void *unused, ...) BSON_GNUC_NULL_TERMINATED; /** * The bcon_..() functions are all declared with __attribute__((sentinel)). * * From GCC manual for "sentinel": "A valid NULL in this context is defined as * zero with any pointer type. If your system defines the NULL macro with an * integer type then you need to add an explicit cast." * Case in point: GCC on Solaris (at least) */ #define BCON_APPEND(_bson, ...) \ bcon_append ((_bson), __VA_ARGS__, (void *)NULL) #define BCON_APPEND_CTX(_bson, _ctx, ...) \ bcon_append_ctx ((_bson), (_ctx), __VA_ARGS__, (void *)NULL) #define BCON_EXTRACT(_bson, ...) \ bcon_extract ((_bson), __VA_ARGS__, (void *)NULL) #define BCON_EXTRACT_CTX(_bson, _ctx, ...) \ bcon_extract ((_bson), (_ctx), __VA_ARGS__, (void *)NULL) #define BCON_NEW(...) \ bcon_new (NULL, __VA_ARGS__, (void *)NULL) const char *bson_bcon_magic (void) BSON_GNUC_CONST; const char *bson_bcone_magic (void) BSON_GNUC_CONST; BSON_END_DECLS #endif mongodb-1.1.5/src/libbson/src/bson/bson-atomic.c0000664000175000017500000000340712673034026021340 0ustar jmikolajmikola/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "bson-atomic.h" /* * We should only ever hit these on non-Windows systems, for which we require * pthread support. Therefore, we will avoid making a threading portability * for threads here and just use pthreads directly. */ #ifdef __BSON_NEED_BARRIER #include static pthread_mutex_t gBarrier = PTHREAD_MUTEX_INITIALIZER; void bson_memory_barrier (void) { pthread_mutex_lock (&gBarrier); pthread_mutex_unlock (&gBarrier); } #endif #ifdef __BSON_NEED_ATOMIC_32 #warning "Using mutex to emulate 32-bit atomics." #include static pthread_mutex_t gSync32 = PTHREAD_MUTEX_INITIALIZER; int32_t bson_atomic_int_add (volatile int32_t *p, int32_t n) { int ret; pthread_mutex_lock (&gSync32); *p += n; ret = *p; pthread_mutex_unlock (&gSync32); return ret; } #endif #ifdef __BSON_NEED_ATOMIC_64 #include static pthread_mutex_t gSync64 = PTHREAD_MUTEX_INITIALIZER; int64_t bson_atomic_int64_add (volatile int64_t *p, int64_t n) { int64_t ret; pthread_mutex_lock (&gSync64); *p += n; ret = *p; pthread_mutex_unlock (&gSync64); return ret; } #endif mongodb-1.1.5/src/libbson/src/bson/bson-atomic.h0000664000175000017500000000541612673034026021347 0ustar jmikolajmikola/* * Copyright 2013-2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef BSON_ATOMIC_H #define BSON_ATOMIC_H #include "bson-config.h" #include "bson-compat.h" #include "bson-macros.h" BSON_BEGIN_DECLS #if defined(__sun) && defined(__SVR4) /* Solaris */ # include # define bson_atomic_int_add(p,v) atomic_add_32_nv((volatile uint32_t *)p, (v)) # define bson_atomic_int64_add(p,v) atomic_add_64_nv((volatile uint64_t *)p, (v)) #elif defined(_WIN32) /* MSVC/MinGW */ # define bson_atomic_int_add(p, v) (InterlockedExchangeAdd((volatile LONG *)(p), (LONG)(v)) + (LONG)(v)) # define bson_atomic_int64_add(p, v) (InterlockedExchangeAdd64((volatile LONGLONG *)(p), (LONGLONG)(v)) + (LONGLONG)(v)) #else # ifdef BSON_HAVE_ATOMIC_32_ADD_AND_FETCH # define bson_atomic_int_add(p,v) __sync_add_and_fetch((p), (v)) # else # define __BSON_NEED_ATOMIC_32 # endif # ifdef BSON_HAVE_ATOMIC_64_ADD_AND_FETCH # if BSON_GNUC_IS_VERSION(4, 1) /* * GCC 4.1 on i386 can generate buggy 64-bit atomic increment. * So we will work around with a fallback. * * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=40693 */ # define __BSON_NEED_ATOMIC_64 # else # define bson_atomic_int64_add(p, v) __sync_add_and_fetch((volatile int64_t*)(p), (int64_t)(v)) # endif # else # define __BSON_NEED_ATOMIC_64 # endif #endif #ifdef __BSON_NEED_ATOMIC_32 int32_t bson_atomic_int_add (volatile int32_t *p, int32_t n); #endif #ifdef __BSON_NEED_ATOMIC_64 int64_t bson_atomic_int64_add (volatile int64_t *p, int64_t n); #endif #if defined(_WIN32) # define bson_memory_barrier() MemoryBarrier() #elif defined(__GNUC__) # if BSON_GNUC_CHECK_VERSION(4, 1) # define bson_memory_barrier() __sync_synchronize() # else # warning "GCC Pre-4.1 discovered, using inline assembly for memory barrier." # define bson_memory_barrier() __asm__ volatile ("":::"memory") # endif #elif defined(__SUNPRO_C) # include # define bson_memory_barrier() __machine_rw_barrier() #elif defined(__xlC__) # define bson_memory_barrier() __sync() #else # define __BSON_NEED_BARRIER 1 # warning "Unknown compiler, using lock for compiler barrier." void bson_memory_barrier (void); #endif BSON_END_DECLS #endif /* BSON_ATOMIC_H */ mongodb-1.1.5/src/libbson/src/bson/bson-clock.c0000664000175000017500000000730612673034026021161 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifdef __APPLE__ # include # include # include # include #endif #include "bson-config.h" #include "bson-compat.h" #if defined(BSON_HAVE_CLOCK_GETTIME) # include # include #endif #include "bson-clock.h" /* *-------------------------------------------------------------------------- * * bson_gettimeofday -- * * A wrapper around gettimeofday() with fallback support for Windows. * * Returns: * 0 if successful. * * Side effects: * @tv is set. * *-------------------------------------------------------------------------- */ int bson_gettimeofday (struct timeval *tv) /* OUT */ { #if defined(_WIN32) # if defined(_MSC_VER) # define DELTA_EPOCH_IN_MICROSEC 11644473600000000Ui64 # else # define DELTA_EPOCH_IN_MICROSEC 11644473600000000ULL # endif FILETIME ft; uint64_t tmp = 0; /* * The const value is shamelessy stolen from * http://www.boost.org/doc/libs/1_55_0/boost/chrono/detail/inlined/win/chrono.hpp * * File times are the number of 100 nanosecond intervals elapsed since * 12:00 am Jan 1, 1601 UTC. I haven't check the math particularly hard * * ... good luck */ if (tv) { GetSystemTimeAsFileTime (&ft); /* pull out of the filetime into a 64 bit uint */ tmp |= ft.dwHighDateTime; tmp <<= 32; tmp |= ft.dwLowDateTime; /* convert from 100's of nanosecs to microsecs */ tmp /= 10; /* adjust to unix epoch */ tmp -= DELTA_EPOCH_IN_MICROSEC; tv->tv_sec = (long)(tmp / 1000000UL); tv->tv_usec = (long)(tmp % 1000000UL); } return 0; #else return gettimeofday (tv, NULL); #endif } /* *-------------------------------------------------------------------------- * * bson_get_monotonic_time -- * * Returns the monotonic system time, if available. A best effort is * made to use the monotonic clock. However, some systems may not * support such a feature. * * Returns: * The monotonic clock in microseconds. * * Side effects: * None. * *-------------------------------------------------------------------------- */ int64_t bson_get_monotonic_time (void) { #if defined(BSON_HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) struct timespec ts; clock_gettime (CLOCK_MONOTONIC, &ts); return ((ts.tv_sec * 1000000UL) + (ts.tv_nsec / 1000UL)); #elif defined(__APPLE__) static mach_timebase_info_data_t info = { 0 }; static double ratio = 0.0; if (!info.denom) { // the value from mach_absolute_time () * info.numer / info.denom // is in nano seconds. So we have to divid by 1000.0 to get micro seconds mach_timebase_info (&info); ratio = (double)info.numer / (double)info.denom / 1000.0; } return mach_absolute_time () * ratio; #elif defined(_WIN32) /* Despite it's name, this is in milliseconds! */ int64_t ticks = GetTickCount64 (); return (ticks * 1000L); #else # warning "Monotonic clock is not yet supported on your platform." struct timeval tv; bson_gettimeofday (&tv); return (tv.tv_sec * 1000000UL) + tv.tv_usec; #endif } mongodb-1.1.5/src/libbson/src/bson/bson-clock.h0000664000175000017500000000174012673034026021162 0ustar jmikolajmikola/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef BSON_CLOCK_H #define BSON_CLOCK_H #if !defined (BSON_INSIDE) && !defined (BSON_COMPILATION) # error "Only can be included directly." #endif #include "bson-compat.h" #include "bson-macros.h" #include "bson-types.h" BSON_BEGIN_DECLS int64_t bson_get_monotonic_time (void); int bson_gettimeofday (struct timeval *tv); BSON_END_DECLS #endif /* BSON_CLOCK_H */ mongodb-1.1.5/src/libbson/src/bson/bson-compat.h0000664000175000017500000000716212673034026021356 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef BSON_COMPAT_H #define BSON_COMPAT_H #if !defined (BSON_INSIDE) && !defined (BSON_COMPILATION) # error "Only can be included directly." #endif #if defined(__MINGW32__) # if defined(__USE_MINGW_ANSI_STDIO) # if __USE_MINGW_ANSI_STDIO < 1 # error "__USE_MINGW_ANSI_STDIO > 0 is required for correct PRI* macros" # endif # else # define __USE_MINGW_ANSI_STDIO 1 # endif #endif #include "bson-config.h" #include "bson-macros.h" #ifdef BSON_OS_WIN32 # if defined(_WIN32_WINNT) && (_WIN32_WINNT < 0x0600) # undef _WIN32_WINNT # endif # ifndef _WIN32_WINNT # define _WIN32_WINNT 0x0600 # endif # ifndef NOMINMAX # define NOMINMAX # endif # include # ifndef WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN # include # undef WIN32_LEAN_AND_MEAN # else # include # endif #include #include #endif #ifdef BSON_OS_UNIX # include # include #endif #include "bson-macros.h" #include #include #include #include #include #include #include #include #include BSON_BEGIN_DECLS #ifdef _MSC_VER # include "bson-stdint-win32.h" # ifndef __cplusplus /* benign redefinition of type */ # pragma warning (disable :4142) # ifndef _SSIZE_T_DEFINED # define _SSIZE_T_DEFINED typedef SSIZE_T ssize_t; # endif typedef SIZE_T size_t; # pragma warning (default :4142) # else /* * MSVC++ does not include ssize_t, just size_t. * So we need to synthesize that as well. */ # pragma warning (disable :4142) # ifndef _SSIZE_T_DEFINED # define _SSIZE_T_DEFINED typedef SSIZE_T ssize_t; # endif # pragma warning (default :4142) # endif # define PRIi32 "d" # define PRId32 "d" # define PRIu32 "u" # define PRIi64 "I64i" # define PRId64 "I64i" # define PRIu64 "I64u" #else # include "bson-stdint.h" # include #endif #if defined(__MINGW32__) && ! defined(INIT_ONCE_STATIC_INIT) # define INIT_ONCE_STATIC_INIT RTL_RUN_ONCE_INIT typedef RTL_RUN_ONCE INIT_ONCE; #endif #ifdef BSON_HAVE_STDBOOL_H # include #elif !defined(__bool_true_false_are_defined) # ifndef __cplusplus typedef signed char bool; # define false 0 # define true 1 # endif # define __bool_true_false_are_defined 1 #endif #if defined(__GNUC__) # if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) # define bson_sync_synchronize() __sync_synchronize() # elif defined(__i386__ ) || defined( __i486__ ) || defined( __i586__ ) || \ defined( __i686__ ) || defined( __x86_64__ ) # define bson_sync_synchronize() asm volatile("mfence":::"memory") # else # define bson_sync_synchronize() asm volatile("sync":::"memory") # endif #elif defined(_MSC_VER) # define bson_sync_synchronize() MemoryBarrier() #endif #if !defined(va_copy) && defined(_MSC_VER) # define va_copy(dst,src) ((dst) = (src)) #endif #if !defined(va_copy) && defined(__GNUC__) && __GNUC__ < 3 # define va_copy(dst,src) __va_copy(dst, src) #endif BSON_END_DECLS #endif /* BSON_COMPAT_H */ mongodb-1.1.5/src/libbson/src/bson/bson-config.h0000664000175000017500000000433012673034026021332 0ustar jmikolajmikola#ifndef BSON_CONFIG_H #define BSON_CONFIG_H /* * Define to 1234 for Little Endian, 4321 for Big Endian. */ #define BSON_BYTE_ORDER 1234 /* * Define to 1 if you have stdbool.h */ #define BSON_HAVE_STDBOOL_H 1 #if BSON_HAVE_STDBOOL_H != 1 # undef BSON_HAVE_STDBOOL_H #endif /* * Define to 1 for POSIX-like systems, 2 for Windows. */ #define BSON_OS 1 /* * Define to 1 if we have access to GCC 32-bit atomic builtins. * While this requires GCC 4.1+ in most cases, it is also architecture * dependent. For example, some PPC or ARM systems may not have it even * if it is a recent GCC version. */ #define BSON_HAVE_ATOMIC_32_ADD_AND_FETCH 1 #if BSON_HAVE_ATOMIC_32_ADD_AND_FETCH != 1 # undef BSON_HAVE_ATOMIC_32_ADD_AND_FETCH #endif /* * Similarly, define to 1 if we have access to GCC 64-bit atomic builtins. */ #define BSON_HAVE_ATOMIC_64_ADD_AND_FETCH 1 #if BSON_HAVE_ATOMIC_64_ADD_AND_FETCH != 1 # undef BSON_HAVE_ATOMIC_64_ADD_AND_FETCH #endif /* * Define to 1 if your system requires {} around PTHREAD_ONCE_INIT. * This is typically just Solaris 8-10. */ #define BSON_PTHREAD_ONCE_INIT_NEEDS_BRACES 0 #if BSON_PTHREAD_ONCE_INIT_NEEDS_BRACES != 1 # undef BSON_PTHREAD_ONCE_INIT_NEEDS_BRACES #endif /* * Define to 1 if you have clock_gettime() available. */ #define BSON_HAVE_CLOCK_GETTIME 1 #if BSON_HAVE_CLOCK_GETTIME != 1 # undef BSON_HAVE_CLOCK_GETTIME #endif /* * Define to 1 if you have strnlen available on your platform. */ #define BSON_HAVE_STRNLEN 1 #if BSON_HAVE_STRNLEN != 1 # undef BSON_HAVE_STRNLEN #endif /* * Define to 1 if you have snprintf available on your platform. */ #define BSON_HAVE_SNPRINTF 1 #if BSON_HAVE_SNPRINTF != 1 # undef BSON_HAVE_SNPRINTF #endif /* * Define to 1 if you have _set_output_format (VS2013 and older). */ #define BSON_NEEDS_SET_OUTPUT_FORMAT 0 #if BSON_NEEDS_SET_OUTPUT_FORMAT != 1 # undef BSON_NEEDS_SET_OUTPUT_FORMAT #endif /* * Define to 1 if you have struct timespec available on your platform. */ #define BSON_HAVE_TIMESPEC 1 #if BSON_HAVE_TIMESPEC != 1 # undef BSON_HAVE_TIMESPEC #endif /* * Define to 1 if you want extra aligned types in libbson */ #define BSON_EXTRA_ALIGN 0 #if BSON_EXTRA_ALIGN != 1 # undef BSON_EXTRA_ALIGN #endif #endif /* BSON_CONFIG_H */ mongodb-1.1.5/src/libbson/src/bson/bson-config.h.in0000664000175000017500000000474712673034026021753 0ustar jmikolajmikola#ifndef BSON_CONFIG_H #define BSON_CONFIG_H /* * Define to 1234 for Little Endian, 4321 for Big Endian. */ #define BSON_BYTE_ORDER @BSON_BYTE_ORDER@ /* * Define to 1 if you have stdbool.h */ #define BSON_HAVE_STDBOOL_H @BSON_HAVE_STDBOOL_H@ #if BSON_HAVE_STDBOOL_H != 1 # undef BSON_HAVE_STDBOOL_H #endif /* * Define to 1 for POSIX-like systems, 2 for Windows. */ #define BSON_OS @BSON_OS@ /* * Define to 1 if we have access to GCC 32-bit atomic builtins. * While this requires GCC 4.1+ in most cases, it is also architecture * dependent. For example, some PPC or ARM systems may not have it even * if it is a recent GCC version. */ #define BSON_HAVE_ATOMIC_32_ADD_AND_FETCH @BSON_HAVE_ATOMIC_32_ADD_AND_FETCH@ #if BSON_HAVE_ATOMIC_32_ADD_AND_FETCH != 1 # undef BSON_HAVE_ATOMIC_32_ADD_AND_FETCH #endif /* * Similarly, define to 1 if we have access to GCC 64-bit atomic builtins. */ #define BSON_HAVE_ATOMIC_64_ADD_AND_FETCH @BSON_HAVE_ATOMIC_64_ADD_AND_FETCH@ #if BSON_HAVE_ATOMIC_64_ADD_AND_FETCH != 1 # undef BSON_HAVE_ATOMIC_64_ADD_AND_FETCH #endif /* * Define to 1 if your system requires {} around PTHREAD_ONCE_INIT. * This is typically just Solaris 8-10. */ #define BSON_PTHREAD_ONCE_INIT_NEEDS_BRACES @BSON_PTHREAD_ONCE_INIT_NEEDS_BRACES@ #if BSON_PTHREAD_ONCE_INIT_NEEDS_BRACES != 1 # undef BSON_PTHREAD_ONCE_INIT_NEEDS_BRACES #endif /* * Define to 1 if you have clock_gettime() available. */ #define BSON_HAVE_CLOCK_GETTIME @BSON_HAVE_CLOCK_GETTIME@ #if BSON_HAVE_CLOCK_GETTIME != 1 # undef BSON_HAVE_CLOCK_GETTIME #endif /* * Define to 1 if you have strnlen available on your platform. */ #define BSON_HAVE_STRNLEN @BSON_HAVE_STRNLEN@ #if BSON_HAVE_STRNLEN != 1 # undef BSON_HAVE_STRNLEN #endif /* * Define to 1 if you have snprintf available on your platform. */ #define BSON_HAVE_SNPRINTF @BSON_HAVE_SNPRINTF@ #if BSON_HAVE_SNPRINTF != 1 # undef BSON_HAVE_SNPRINTF #endif /* * Define to 1 if you have _set_output_format (VS2013 and older). */ #define BSON_NEEDS_SET_OUTPUT_FORMAT @BSON_NEEDS_SET_OUTPUT_FORMAT@ #if BSON_NEEDS_SET_OUTPUT_FORMAT != 1 # undef BSON_NEEDS_SET_OUTPUT_FORMAT #endif /* * Define to 1 if you have struct timespec available on your platform. */ #define BSON_HAVE_TIMESPEC @BSON_HAVE_TIMESPEC@ #if BSON_HAVE_TIMESPEC != 1 # undef BSON_HAVE_TIMESPEC #endif /* * Define to 1 if you want extra aligned types in libbson */ #define BSON_EXTRA_ALIGN @BSON_EXTRA_ALIGN@ #if BSON_EXTRA_ALIGN != 1 # undef BSON_EXTRA_ALIGN #endif #endif /* BSON_CONFIG_H */ mongodb-1.1.5/src/libbson/src/bson/bson-context-private.h0000664000175000017500000000262012673034026023221 0ustar jmikolajmikola/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef BSON_CONTEXT_PRIVATE_H #define BSON_CONTEXT_PRIVATE_H #include "bson-context.h" #include "bson-thread-private.h" BSON_BEGIN_DECLS struct _bson_context_t { bson_context_flags_t flags : 7; bool pidbe_once : 1; uint8_t pidbe[2]; uint8_t md5[3]; int32_t seq32; int64_t seq64; void (*oid_get_host) (bson_context_t *context, bson_oid_t *oid); void (*oid_get_pid) (bson_context_t *context, bson_oid_t *oid); void (*oid_get_seq32) (bson_context_t *context, bson_oid_t *oid); void (*oid_get_seq64) (bson_context_t *context, bson_oid_t *oid); }; BSON_END_DECLS #endif /* BSON_CONTEXT_PRIVATE_H */ mongodb-1.1.5/src/libbson/src/bson/bson-context.c0000664000175000017500000003001112673034026021537 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "bson-compat.h" #include #include #include #include #include #if defined(__linux__) #include #endif #include "bson-atomic.h" #include "bson-clock.h" #include "bson-context.h" #include "bson-context-private.h" #include "bson-md5.h" #include "bson-memory.h" #include "bson-thread-private.h" #ifndef HOST_NAME_MAX #define HOST_NAME_MAX 256 #endif /* * Globals. */ static bson_context_t gContextDefault; #if defined(__linux__) static uint16_t gettid (void) { return syscall (SYS_gettid); } #endif /* *-------------------------------------------------------------------------- * * _bson_context_get_oid_host -- * * Retrieves the first three bytes of MD5(hostname) and assigns them * to the host portion of oid. * * Returns: * None. * * Side effects: * @oid is modified. * *-------------------------------------------------------------------------- */ static void _bson_context_get_oid_host (bson_context_t *context, /* IN */ bson_oid_t *oid) /* OUT */ { uint8_t *bytes = (uint8_t *)oid; uint8_t digest[16]; bson_md5_t md5; char hostname[HOST_NAME_MAX]; BSON_ASSERT (context); BSON_ASSERT (oid); gethostname (hostname, sizeof hostname); hostname[HOST_NAME_MAX - 1] = '\0'; bson_md5_init (&md5); bson_md5_append (&md5, (const uint8_t *)hostname, (uint32_t)strlen (hostname)); bson_md5_finish (&md5, &digest[0]); bytes[4] = digest[0]; bytes[5] = digest[1]; bytes[6] = digest[2]; } /* *-------------------------------------------------------------------------- * * _bson_context_get_oid_host_cached -- * * Fetch the cached copy of the MD5(hostname). * * Returns: * None. * * Side effects: * @oid is modified. * *-------------------------------------------------------------------------- */ static void _bson_context_get_oid_host_cached (bson_context_t *context, /* IN */ bson_oid_t *oid) /* OUT */ { BSON_ASSERT (context); BSON_ASSERT (oid); oid->bytes[4] = context->md5[0]; oid->bytes[5] = context->md5[1]; oid->bytes[6] = context->md5[2]; } static BSON_INLINE uint16_t _bson_getpid (void) { uint16_t pid; #ifdef BSON_OS_WIN32 DWORD real_pid; real_pid = GetCurrentProcessId (); pid = (real_pid & 0xFFFF) ^ ((real_pid >> 16) & 0xFFFF); #else pid = getpid (); #endif return pid; } /* *-------------------------------------------------------------------------- * * _bson_context_get_oid_pid -- * * Initialize the pid field of @oid. * * The pid field is 2 bytes, big-endian for memcmp(). * * Returns: * None. * * Side effects: * @oid is modified. * *-------------------------------------------------------------------------- */ static void _bson_context_get_oid_pid (bson_context_t *context, /* IN */ bson_oid_t *oid) /* OUT */ { uint16_t pid = _bson_getpid (); uint8_t *bytes = (uint8_t *)&pid; BSON_ASSERT (context); BSON_ASSERT (oid); pid = BSON_UINT16_TO_BE (pid); oid->bytes[7] = bytes[0]; oid->bytes[8] = bytes[1]; } /* *-------------------------------------------------------------------------- * * _bson_context_get_oid_pid_cached -- * * Fetch the cached copy of the current pid. * This helps avoid multiple calls to getpid() which is slower * on some systems. * * Returns: * None. * * Side effects: * @oid is modified. * *-------------------------------------------------------------------------- */ static void _bson_context_get_oid_pid_cached (bson_context_t *context, /* IN */ bson_oid_t *oid) /* OUT */ { oid->bytes[7] = context->pidbe[0]; oid->bytes[8] = context->pidbe[1]; } /* *-------------------------------------------------------------------------- * * _bson_context_get_oid_seq32 -- * * 32-bit sequence generator, non-thread-safe version. * * Returns: * None. * * Side effects: * @oid is modified. * *-------------------------------------------------------------------------- */ static void _bson_context_get_oid_seq32 (bson_context_t *context, /* IN */ bson_oid_t *oid) /* OUT */ { uint32_t seq = context->seq32++; seq = BSON_UINT32_TO_BE (seq); memcpy (&oid->bytes[9], ((uint8_t *)&seq) + 1, 3); } /* *-------------------------------------------------------------------------- * * _bson_context_get_oid_seq32_threadsafe -- * * Thread-safe version of 32-bit sequence generator. * * Returns: * None. * * Side effects: * @oid is modified. * *-------------------------------------------------------------------------- */ static void _bson_context_get_oid_seq32_threadsafe (bson_context_t *context, /* IN */ bson_oid_t *oid) /* OUT */ { int32_t seq = bson_atomic_int_add (&context->seq32, 1); seq = BSON_UINT32_TO_BE (seq); memcpy (&oid->bytes[9], ((uint8_t *)&seq) + 1, 3); } /* *-------------------------------------------------------------------------- * * _bson_context_get_oid_seq64 -- * * 64-bit oid sequence generator, non-thread-safe version. * * Returns: * None. * * Side effects: * @oid is modified. * *-------------------------------------------------------------------------- */ static void _bson_context_get_oid_seq64 (bson_context_t *context, /* IN */ bson_oid_t *oid) /* OUT */ { uint64_t seq; BSON_ASSERT (context); BSON_ASSERT (oid); seq = BSON_UINT64_TO_BE (context->seq64++); memcpy (&oid->bytes[4], &seq, sizeof (seq)); } /* *-------------------------------------------------------------------------- * * _bson_context_get_oid_seq64_threadsafe -- * * Thread-safe 64-bit sequence generator. * * Returns: * None. * * Side effects: * @oid is modified. * *-------------------------------------------------------------------------- */ static void _bson_context_get_oid_seq64_threadsafe (bson_context_t *context, /* IN */ bson_oid_t *oid) /* OUT */ { int64_t seq = bson_atomic_int64_add (&context->seq64, 1); seq = BSON_UINT64_TO_BE (seq); memcpy (&oid->bytes[4], &seq, sizeof (seq)); } static void _bson_context_init (bson_context_t *context, /* IN */ bson_context_flags_t flags) /* IN */ { struct timeval tv; uint16_t pid; unsigned int seed[3]; unsigned int real_seed; bson_oid_t oid; context->flags = flags; context->oid_get_host = _bson_context_get_oid_host_cached; context->oid_get_pid = _bson_context_get_oid_pid_cached; context->oid_get_seq32 = _bson_context_get_oid_seq32; context->oid_get_seq64 = _bson_context_get_oid_seq64; /* * Generate a seed for our the random starting position of our increment * bytes. We mask off the last nibble so that the last digit of the OID will * start at zero. Just to be nice. * * The seed itself is made up of the current time in seconds, milliseconds, * and pid xored together. I welcome better solutions if at all necessary. */ bson_gettimeofday (&tv); seed[0] = (unsigned int)tv.tv_sec; seed[1] = (unsigned int)tv.tv_usec; seed[2] = _bson_getpid (); real_seed = seed[0] ^ seed[1] ^ seed[2]; #ifdef BSON_OS_WIN32 /* ms's runtime is multithreaded by default, so no rand_r */ srand(real_seed); context->seq32 = rand() & 0x007FFFF0; #else context->seq32 = rand_r (&real_seed) & 0x007FFFF0; #endif if ((flags & BSON_CONTEXT_DISABLE_HOST_CACHE)) { context->oid_get_host = _bson_context_get_oid_host; } else { _bson_context_get_oid_host (context, &oid); context->md5[0] = oid.bytes[4]; context->md5[1] = oid.bytes[5]; context->md5[2] = oid.bytes[6]; } if ((flags & BSON_CONTEXT_THREAD_SAFE)) { context->oid_get_seq32 = _bson_context_get_oid_seq32_threadsafe; context->oid_get_seq64 = _bson_context_get_oid_seq64_threadsafe; } if ((flags & BSON_CONTEXT_DISABLE_PID_CACHE)) { context->oid_get_pid = _bson_context_get_oid_pid; } else { pid = BSON_UINT16_TO_BE (_bson_getpid()); #if defined(__linux__) if ((flags & BSON_CONTEXT_USE_TASK_ID)) { int32_t tid; if ((tid = gettid ())) { pid = BSON_UINT16_TO_BE (tid); } } #endif memcpy (&context->pidbe[0], &pid, 2); } } /* *-------------------------------------------------------------------------- * * bson_context_new -- * * Initializes a new context with the flags specified. * * In most cases, you want to call this with @flags set to * BSON_CONTEXT_NONE. * * If you are running on Linux, %BSON_CONTEXT_USE_TASK_ID can result * in a healthy speedup for multi-threaded scenarios. * * If you absolutely must have a single context for your application * and use more than one thread, then %BSON_CONTEXT_THREAD_SAFE should * be bitwise-or'd with your flags. This requires synchronization * between threads. * * If you expect your hostname to change often, you may consider * specifying %BSON_CONTEXT_DISABLE_HOST_CACHE so that gethostname() * is called for every OID generated. This is much slower. * * If you expect your pid to change without notice, such as from an * unexpected call to fork(), then specify * %BSON_CONTEXT_DISABLE_PID_CACHE. * * Returns: * A newly allocated bson_context_t that should be freed with * bson_context_destroy(). * * Side effects: * None. * *-------------------------------------------------------------------------- */ bson_context_t * bson_context_new (bson_context_flags_t flags) { bson_context_t *context; context = bson_malloc0 (sizeof *context); _bson_context_init (context, flags); return context; } /* *-------------------------------------------------------------------------- * * bson_context_destroy -- * * Cleans up a bson_context_t and releases any associated resources. * This should be called when you are done using @context. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void bson_context_destroy (bson_context_t *context) /* IN */ { if (context != &gContextDefault) { memset (context, 0, sizeof *context); bson_free (context); } } static BSON_ONCE_FUN(_bson_context_init_default) { _bson_context_init (&gContextDefault, (BSON_CONTEXT_THREAD_SAFE | BSON_CONTEXT_DISABLE_PID_CACHE)); BSON_ONCE_RETURN; } /* *-------------------------------------------------------------------------- * * bson_context_get_default -- * * Fetches the default, thread-safe implementation of #bson_context_t. * If you need faster generation, it is recommended you create your * own #bson_context_t with bson_context_new(). * * Returns: * A shared instance to the default #bson_context_t. This should not * be modified or freed. * * Side effects: * None. * *-------------------------------------------------------------------------- */ bson_context_t * bson_context_get_default (void) { static bson_once_t once = BSON_ONCE_INIT; bson_once (&once, _bson_context_init_default); return &gContextDefault; } mongodb-1.1.5/src/libbson/src/bson/bson-context.h0000664000175000017500000000207312673034026021553 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef BSON_CONTEXT_H #define BSON_CONTEXT_H #if !defined (BSON_INSIDE) && !defined (BSON_COMPILATION) # error "Only can be included directly." #endif #include "bson-macros.h" #include "bson-types.h" BSON_BEGIN_DECLS bson_context_t *bson_context_new (bson_context_flags_t flags); void bson_context_destroy (bson_context_t *context); bson_context_t *bson_context_get_default (void) BSON_GNUC_CONST; BSON_END_DECLS #endif /* BSON_CONTEXT_H */ mongodb-1.1.5/src/libbson/src/bson/bson-endian.h0000664000175000017500000001464612673034026021336 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef BSON_ENDIAN_H #define BSON_ENDIAN_H #if !defined (BSON_INSIDE) && !defined (BSON_COMPILATION) # error "Only can be included directly." #endif #if defined(__sun) # include #endif #include "bson-config.h" #include "bson-macros.h" #include "bson-compat.h" BSON_BEGIN_DECLS #define BSON_BIG_ENDIAN 4321 #define BSON_LITTLE_ENDIAN 1234 #if defined(__sun) # define BSON_UINT16_SWAP_LE_BE(v) BSWAP_16((uint16_t)v) # define BSON_UINT32_SWAP_LE_BE(v) BSWAP_32((uint32_t)v) # define BSON_UINT64_SWAP_LE_BE(v) BSWAP_64((uint64_t)v) #elif defined(__clang__) && defined(__clang_major__) && defined(__clang_minor__) && \ (__clang_major__ >= 3) && (__clang_minor__ >= 1) # if __has_builtin(__builtin_bswap16) # define BSON_UINT16_SWAP_LE_BE(v) __builtin_bswap16(v) # endif # if __has_builtin(__builtin_bswap32) # define BSON_UINT32_SWAP_LE_BE(v) __builtin_bswap32(v) # endif # if __has_builtin(__builtin_bswap64) # define BSON_UINT64_SWAP_LE_BE(v) __builtin_bswap64(v) # endif #elif defined(__GNUC__) && (__GNUC__ >= 4) # if __GNUC__ >= 4 && defined (__GNUC_MINOR__) && __GNUC_MINOR__ >= 3 # define BSON_UINT32_SWAP_LE_BE(v) __builtin_bswap32 ((uint32_t)v) # define BSON_UINT64_SWAP_LE_BE(v) __builtin_bswap64 ((uint64_t)v) # endif # if __GNUC__ >= 4 && defined (__GNUC_MINOR__) && __GNUC_MINOR__ >= 8 # define BSON_UINT16_SWAP_LE_BE(v) __builtin_bswap16 ((uint32_t)v) # endif #endif #ifndef BSON_UINT16_SWAP_LE_BE # define BSON_UINT16_SWAP_LE_BE(v) __bson_uint16_swap_slow ((uint16_t)v) #endif #ifndef BSON_UINT32_SWAP_LE_BE # define BSON_UINT32_SWAP_LE_BE(v) __bson_uint32_swap_slow ((uint32_t)v) #endif #ifndef BSON_UINT64_SWAP_LE_BE # define BSON_UINT64_SWAP_LE_BE(v) __bson_uint64_swap_slow ((uint64_t)v) #endif #if BSON_BYTE_ORDER == BSON_LITTLE_ENDIAN # define BSON_UINT16_FROM_LE(v) ((uint16_t)v) # define BSON_UINT16_TO_LE(v) ((uint16_t)v) # define BSON_UINT16_FROM_BE(v) BSON_UINT16_SWAP_LE_BE (v) # define BSON_UINT16_TO_BE(v) BSON_UINT16_SWAP_LE_BE (v) # define BSON_UINT32_FROM_LE(v) ((uint32_t)v) # define BSON_UINT32_TO_LE(v) ((uint32_t)v) # define BSON_UINT32_FROM_BE(v) BSON_UINT32_SWAP_LE_BE (v) # define BSON_UINT32_TO_BE(v) BSON_UINT32_SWAP_LE_BE (v) # define BSON_UINT64_FROM_LE(v) ((uint64_t)v) # define BSON_UINT64_TO_LE(v) ((uint64_t)v) # define BSON_UINT64_FROM_BE(v) BSON_UINT64_SWAP_LE_BE (v) # define BSON_UINT64_TO_BE(v) BSON_UINT64_SWAP_LE_BE (v) # define BSON_DOUBLE_FROM_LE(v) ((double)v) # define BSON_DOUBLE_TO_LE(v) ((double)v) #elif BSON_BYTE_ORDER == BSON_BIG_ENDIAN # define BSON_UINT16_FROM_LE(v) BSON_UINT16_SWAP_LE_BE (v) # define BSON_UINT16_TO_LE(v) BSON_UINT16_SWAP_LE_BE (v) # define BSON_UINT16_FROM_BE(v) ((uint16_t)v) # define BSON_UINT16_TO_BE(v) ((uint16_t)v) # define BSON_UINT32_FROM_LE(v) BSON_UINT32_SWAP_LE_BE (v) # define BSON_UINT32_TO_LE(v) BSON_UINT32_SWAP_LE_BE (v) # define BSON_UINT32_FROM_BE(v) ((uint32_t)v) # define BSON_UINT32_TO_BE(v) ((uint32_t)v) # define BSON_UINT64_FROM_LE(v) BSON_UINT64_SWAP_LE_BE (v) # define BSON_UINT64_TO_LE(v) BSON_UINT64_SWAP_LE_BE (v) # define BSON_UINT64_FROM_BE(v) ((uint64_t)v) # define BSON_UINT64_TO_BE(v) ((uint64_t)v) # define BSON_DOUBLE_FROM_LE(v) (__bson_double_swap_slow (v)) # define BSON_DOUBLE_TO_LE(v) (__bson_double_swap_slow (v)) #else # error "The endianness of target architecture is unknown." #endif /* *-------------------------------------------------------------------------- * * __bson_uint16_swap_slow -- * * Fallback endianness conversion for 16-bit integers. * * Returns: * The endian swapped version. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static BSON_INLINE uint16_t __bson_uint16_swap_slow (uint16_t v) /* IN */ { return ((v & 0x00FF) << 8) | ((v & 0xFF00) >> 8); } /* *-------------------------------------------------------------------------- * * __bson_uint32_swap_slow -- * * Fallback endianness conversion for 32-bit integers. * * Returns: * The endian swapped version. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static BSON_INLINE uint32_t __bson_uint32_swap_slow (uint32_t v) /* IN */ { return ((v & 0x000000FFU) << 24) | ((v & 0x0000FF00U) << 8) | ((v & 0x00FF0000U) >> 8) | ((v & 0xFF000000U) >> 24); } /* *-------------------------------------------------------------------------- * * __bson_uint64_swap_slow -- * * Fallback endianness conversion for 64-bit integers. * * Returns: * The endian swapped version. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static BSON_INLINE uint64_t __bson_uint64_swap_slow (uint64_t v) /* IN */ { return ((v & 0x00000000000000FFULL) << 56) | ((v & 0x000000000000FF00ULL) << 40) | ((v & 0x0000000000FF0000ULL) << 24) | ((v & 0x00000000FF000000ULL) << 8) | ((v & 0x000000FF00000000ULL) >> 8) | ((v & 0x0000FF0000000000ULL) >> 24) | ((v & 0x00FF000000000000ULL) >> 40) | ((v & 0xFF00000000000000ULL) >> 56); } /* *-------------------------------------------------------------------------- * * __bson_double_swap_slow -- * * Fallback endianness conversion for double floating point. * * Returns: * The endian swapped version. * * Side effects: * None. * *-------------------------------------------------------------------------- */ BSON_STATIC_ASSERT(sizeof(double) == sizeof(uint64_t)); static BSON_INLINE double __bson_double_swap_slow (double v) /* IN */ { uint64_t uv; memcpy(&uv, &v, sizeof(v)); uv = BSON_UINT64_SWAP_LE_BE(uv); memcpy(&v, &uv, sizeof(v)); return v; } BSON_END_DECLS #endif /* BSON_ENDIAN_H */ mongodb-1.1.5/src/libbson/src/bson/bson-error.c0000664000175000017500000000621012673034026021210 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include "bson-compat.h" #include "bson-config.h" #include "bson-error.h" #include "bson-memory.h" #include "bson-string.h" #include "bson-types.h" /* *-------------------------------------------------------------------------- * * bson_set_error -- * * Initializes @error using the parameters specified. * * @domain is an application specific error domain which should * describe which module initiated the error. Think of this as the * exception type. * * @code is the @domain specific error code. * * @format is used to generate the format string. It uses vsnprintf() * internally so the format should match what you would use there. * * Parameters: * @error: A #bson_error_t. * @domain: The error domain. * @code: The error code. * @format: A printf style format string. * * Returns: * None. * * Side effects: * @error is initialized. * *-------------------------------------------------------------------------- */ void bson_set_error (bson_error_t *error, /* OUT */ uint32_t domain, /* IN */ uint32_t code, /* IN */ const char *format, /* IN */ ...) /* IN */ { va_list args; if (error) { error->domain = domain; error->code = code; va_start (args, format); bson_vsnprintf (error->message, sizeof error->message, format, args); va_end (args); error->message[sizeof error->message - 1] = '\0'; } } /* *-------------------------------------------------------------------------- * * bson_strerror_r -- * * This is a reentrant safe macro for strerror. * * The resulting string may be stored in @buf. * * Returns: * A pointer to a static string or @buf. * * Side effects: * None. * *-------------------------------------------------------------------------- */ char * bson_strerror_r (int err_code, /* IN */ char *buf, /* IN */ size_t buflen) /* IN */ { static const char *unknown_msg = "Unknown error"; char *ret = NULL; #if defined(__GNUC__) && defined(_GNU_SOURCE) ret = strerror_r (err_code, buf, buflen); #elif defined(_WIN32) if (strerror_s (buf, buflen, err_code) != 0) { ret = buf; } #else /* XSI strerror_r */ if (strerror_r (err_code, buf, buflen) == 0) { ret = buf; } #endif if (!ret) { bson_strncpy (buf, unknown_msg, buflen); ret = buf; } return ret; } mongodb-1.1.5/src/libbson/src/bson/bson-error.h0000664000175000017500000000233412673034026021220 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef BSON_ERROR_H #define BSON_ERROR_H #include "bson-compat.h" #include "bson-macros.h" #include "bson-types.h" BSON_BEGIN_DECLS #define BSON_ERROR_JSON 1 #define BSON_ERROR_READER 2 #define BSON_ERROR_BUFFER_SIZE 64 void bson_set_error (bson_error_t *error, uint32_t domain, uint32_t code, const char *format, ...) BSON_GNUC_PRINTF (4, 5); char *bson_strerror_r (int err_code, char *buf, size_t buflen); BSON_END_DECLS #endif /* BSON_ERROR_H */ mongodb-1.1.5/src/libbson/src/bson/bson-iso8601-private.h0000664000175000017500000000163612673034026022654 0ustar jmikolajmikola/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef BSON_ISO8601_PRIVATE_H #define BSON_ISO8601_PRIVATE_H #include "bson-compat.h" #include "bson-macros.h" BSON_BEGIN_DECLS bool _bson_iso8601_date_parse (const char *str, int32_t len, int64_t *out); BSON_END_DECLS #endif /* BSON_ISO8601_PRIVATE_H */ mongodb-1.1.5/src/libbson/src/bson/bson-iso8601.c0000664000175000017500000001764712673034026021210 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "bson-compat.h" #include "bson-macros.h" #include "bson-error.h" #include "bson-iso8601-private.h" #ifndef _WIN32 # include "bson-timegm-private.h" #endif static bool get_tok (const char *terminals, const char **ptr, int32_t *remaining, const char **out, int32_t *out_len) { const char *terminal; bool found_terminal = false; if (!*remaining) { *out = ""; *out_len = 0; } *out = *ptr; *out_len = -1; for (; *remaining && !found_terminal; (*ptr)++, (*remaining)--, (*out_len)++) { for (terminal = terminals; *terminal; terminal++) { if (**ptr == *terminal) { found_terminal = true; break; } } } if (!found_terminal) { (*out_len)++; } return found_terminal; } static bool digits_only (const char *str, int32_t len) { int i; for (i = 0; i < len; i++) { if (!isdigit(str[i])) { return false; } } return true; } static bool parse_num (const char *str, int32_t len, int32_t digits, int32_t min, int32_t max, int32_t *out) { int i; int magnitude = 1; int32_t value = 0; if ((digits >= 0 && len != digits) || !digits_only (str, len)) { return false; } for (i = 1; i <= len; i++, magnitude *= 10) { value += (str[len - i] - '0') * magnitude; } if (value < min || value > max) { return false; } *out = value; return true; } bool _bson_iso8601_date_parse (const char *str, int32_t len, int64_t *out) { const char *ptr; int32_t remaining = len; const char *year_ptr; const char *month_ptr; const char *day_ptr; const char *hour_ptr; const char *min_ptr; const char *sec_ptr; const char *millis_ptr; const char *tz_ptr; int32_t year_len = 0; int32_t month_len = 0; int32_t day_len = 0; int32_t hour_len = 0; int32_t min_len = 0; int32_t sec_len = 0; int32_t millis_len = 0; int32_t tz_len = 0; int32_t year; int32_t month; int32_t day; int32_t hour; int32_t min; int32_t sec = 0; int64_t millis = 0; int32_t tz_adjustment = 0; #ifdef BSON_OS_WIN32 SYSTEMTIME win_sys_time; FILETIME win_file_time; int64_t win_time_offset; int64_t win_epoch_difference; #else struct tm posix_date = { 0 }; #endif ptr = str; /* we have to match at least yyyy-mm-ddThh:mm[:+-Z] */ if (!(get_tok ("-", &ptr, &remaining, &year_ptr, &year_len) && get_tok ("-", &ptr, &remaining, &month_ptr, &month_len) && get_tok ("T", &ptr, &remaining, &day_ptr, &day_len) && get_tok (":", &ptr, &remaining, &hour_ptr, &hour_len) && get_tok (":+-Z", &ptr, &remaining, &min_ptr, &min_len))) { return false; } /* if the minute has a ':' at the end look for seconds */ if (min_ptr[min_len] == ':') { if (remaining < 2) { return false; } get_tok (".+-Z", &ptr, &remaining, &sec_ptr, &sec_len); if (!sec_len) { return false; } } /* if we had a second and it is followed by a '.' look for milliseconds */ if (sec_len && sec_ptr[sec_len] == '.') { if (remaining < 2) { return false; } get_tok ("+-Z", &ptr, &remaining, &millis_ptr, &millis_len); if (!millis_len) { return false; } } /* backtrack by 1 to put ptr on the timezone */ ptr--; remaining++; get_tok ("", &ptr, &remaining, &tz_ptr, &tz_len); /* we want to include the last few hours in 1969 for timezones translate * across 1970 GMT. We'll check in timegm later on to make sure we're post * 1970 */ if (!parse_num (year_ptr, year_len, 4, 1969, 9999, &year)) { return false; } /* values are as in struct tm */ year -= 1900; if (!parse_num (month_ptr, month_len, 2, 1, 12, &month)) { return false; } /* values are as in struct tm */ month -= 1; if (!parse_num (day_ptr, day_len, 2, 1, 31, &day)) { return false; } if (!parse_num (hour_ptr, hour_len, 2, 0, 23, &hour)) { return false; } if (!parse_num (min_ptr, min_len, 2, 0, 59, &min)) { return false; } if (sec_len && !parse_num (sec_ptr, sec_len, 2, 0, 60, &sec)) { return false; } if (tz_len > 0) { if (tz_ptr[0] == 'Z' && tz_len == 1) { /* valid */ } else if (tz_ptr[0] == '+' || tz_ptr[0] == '-') { int32_t tz_hour; int32_t tz_min; if (tz_len != 5 || !digits_only (tz_ptr + 1, 4)) { return false; } if (!parse_num (tz_ptr + 1, 2, -1, -23, 23, &tz_hour)) { return false; } if (!parse_num (tz_ptr + 3, 2, -1, 0, 59, &tz_min)) { return false; } /* we inflect the meaning of a 'positive' timezone. Those are hours * we have to substract, and vice versa */ tz_adjustment = (tz_ptr[0] == '-' ? 1 : -1) * ((tz_min * 60) + (tz_hour * 60 * 60)); if (!(tz_adjustment > -86400 && tz_adjustment < 86400)) { return false; } } else { return false; } } if (millis_len > 0) { int i; int magnitude; millis = 0; if (millis_len > 3 || !digits_only (millis_ptr, millis_len)) { return false; } for (i = 1, magnitude = 1; i <= millis_len; i++, magnitude *= 10) { millis += (millis_ptr[millis_len - i] - '0') * magnitude; } if (millis_len == 1) { millis *= 100; } else if (millis_len == 2) { millis *= 10; } if (millis < 0 || millis > 1000) { return false; } } #ifdef BSON_OS_WIN32 win_sys_time.wMilliseconds = millis; win_sys_time.wSecond = sec; win_sys_time.wMinute = min; win_sys_time.wHour = hour; win_sys_time.wDay = day; win_sys_time.wDayOfWeek = -1; /* ignored */ win_sys_time.wMonth = month + 1; win_sys_time.wYear = year + 1900; /* the wDayOfWeek member of SYSTEMTIME is ignored by this function */ if (SystemTimeToFileTime (&win_sys_time, &win_file_time) == 0) { return 0; } /* The Windows FILETIME structure contains two parts of a 64-bit value representing the * number of 100-nanosecond intervals since January 1, 1601 */ win_time_offset = (((uint64_t)win_file_time.dwHighDateTime) << 32) | win_file_time.dwLowDateTime; /* There are 11644473600 seconds between the unix epoch and the windows epoch * 100-nanoseconds = milliseconds * 10000 */ win_epoch_difference = 11644473600000 * 10000; /* removes the diff between 1970 and 1601 */ win_time_offset -= win_epoch_difference; /* 1 milliseconds = 1000000 nanoseconds = 10000 100-nanosecond intervals */ millis = win_time_offset / 10000; #else posix_date.tm_sec = sec; posix_date.tm_min = min; posix_date.tm_hour = hour; posix_date.tm_mday = day; posix_date.tm_mon = month; posix_date.tm_year = year; posix_date.tm_wday = 0; posix_date.tm_yday = 0; millis = (1000 * ((uint64_t)_bson_timegm (&posix_date))) + millis; #endif millis += tz_adjustment * 1000; if (millis < 0) { return false; } *out = millis; return true; } mongodb-1.1.5/src/libbson/src/bson/bson-iter.c0000664000175000017500000014673112673034026021037 0ustar jmikolajmikola/* * Copyright 2013-2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "bson-iter.h" #define ITER_TYPE(i) ((bson_type_t) *((i)->raw + (i)->type)) /* *-------------------------------------------------------------------------- * * bson_iter_init -- * * Initializes @iter to be used to iterate @bson. * * Returns: * true if bson_iter_t was initialized. otherwise false. * * Side effects: * @iter is initialized. * *-------------------------------------------------------------------------- */ bool bson_iter_init (bson_iter_t *iter, /* OUT */ const bson_t *bson) /* IN */ { BSON_ASSERT (iter); BSON_ASSERT (bson); if (BSON_UNLIKELY (bson->len < 5)) { memset (iter, 0, sizeof *iter); return false; } iter->raw = bson_get_data (bson); iter->len = bson->len; iter->off = 0; iter->type = 0; iter->key = 0; iter->d1 = 0; iter->d2 = 0; iter->d3 = 0; iter->d4 = 0; iter->next_off = 4; iter->err_off = 0; return true; } /* *-------------------------------------------------------------------------- * * bson_iter_recurse -- * * Creates a new sub-iter looking at the document or array that @iter * is currently pointing at. * * Returns: * true if successful and @child was initialized. * * Side effects: * @child is initialized. * *-------------------------------------------------------------------------- */ bool bson_iter_recurse (const bson_iter_t *iter, /* IN */ bson_iter_t *child) /* OUT */ { const uint8_t *data = NULL; uint32_t len = 0; BSON_ASSERT (iter); BSON_ASSERT (child); if (ITER_TYPE (iter) == BSON_TYPE_DOCUMENT) { bson_iter_document (iter, &len, &data); } else if (ITER_TYPE (iter) == BSON_TYPE_ARRAY) { bson_iter_array (iter, &len, &data); } else { return false; } child->raw = data; child->len = len; child->off = 0; child->type = 0; child->key = 0; child->d1 = 0; child->d2 = 0; child->d3 = 0; child->d4 = 0; child->next_off = 4; child->err_off = 0; return true; } /* *-------------------------------------------------------------------------- * * bson_iter_init_find -- * * Initializes a #bson_iter_t and moves the iter to the first field * matching @key. * * Returns: * true if the field named @key was found; otherwise false. * * Side effects: * None. * *-------------------------------------------------------------------------- */ bool bson_iter_init_find (bson_iter_t *iter, /* INOUT */ const bson_t *bson, /* IN */ const char *key) /* IN */ { BSON_ASSERT (iter); BSON_ASSERT (bson); BSON_ASSERT (key); return bson_iter_init (iter, bson) && bson_iter_find (iter, key); } /* *-------------------------------------------------------------------------- * * bson_iter_init_find_case -- * * A case-insensitive version of bson_iter_init_find(). * * Returns: * true if the field was found and @iter is observing that field. * * Side effects: * None. * *-------------------------------------------------------------------------- */ bool bson_iter_init_find_case (bson_iter_t *iter, /* INOUT */ const bson_t *bson, /* IN */ const char *key) /* IN */ { BSON_ASSERT (iter); BSON_ASSERT (bson); BSON_ASSERT (key); return bson_iter_init (iter, bson) && bson_iter_find_case (iter, key); } /* *-------------------------------------------------------------------------- * * _bson_iter_find_with_len -- * * Internal helper for finding an exact key. * * Returns: * true if the field @key was found. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static bool _bson_iter_find_with_len (bson_iter_t *iter, /* INOUT */ const char *key, /* IN */ int keylen) /* IN */ { const char *ikey; if (keylen == 0) { return false; } if (keylen < 0) { keylen = (int)strlen (key); } while (bson_iter_next (iter)) { ikey = bson_iter_key (iter); if ((0 == strncmp (key, ikey, keylen)) && (ikey [keylen] == '\0')) { return true; } } return false; } /* *-------------------------------------------------------------------------- * * bson_iter_find -- * * Searches through @iter starting from the current position for a key * matching @key. This is a case-sensitive search meaning "KEY" and * "key" would NOT match. * * Returns: * true if @key is found. * * Side effects: * None. * *-------------------------------------------------------------------------- */ bool bson_iter_find (bson_iter_t *iter, /* INOUT */ const char *key) /* IN */ { BSON_ASSERT (iter); BSON_ASSERT (key); return _bson_iter_find_with_len (iter, key, -1); } /* *-------------------------------------------------------------------------- * * bson_iter_find_case -- * * Searches through @iter starting from the current position for a key * matching @key. This is a case-insensitive search meaning "KEY" and * "key" would match. * * Returns: * true if @key is found. * * Side effects: * None. * *-------------------------------------------------------------------------- */ bool bson_iter_find_case (bson_iter_t *iter, /* INOUT */ const char *key) /* IN */ { BSON_ASSERT (iter); BSON_ASSERT (key); while (bson_iter_next (iter)) { #ifdef BSON_OS_WIN32 if (!_stricmp(key, bson_iter_key (iter))) { #else if (!strcasecmp (key, bson_iter_key (iter))) { #endif return true; } } return false; } /* *-------------------------------------------------------------------------- * * bson_iter_find_descendant -- * * Locates a descendant using the "parent.child.key" notation. This * operates similar to bson_iter_find() except that it can recurse * into children documents using the dot notation. * * Returns: * true if the descendant was found and @descendant was initialized. * * Side effects: * @descendant may be initialized. * *-------------------------------------------------------------------------- */ bool bson_iter_find_descendant (bson_iter_t *iter, /* INOUT */ const char *dotkey, /* IN */ bson_iter_t *descendant) /* OUT */ { bson_iter_t tmp; const char *dot; size_t sublen; BSON_ASSERT (iter); BSON_ASSERT (dotkey); BSON_ASSERT (descendant); if ((dot = strchr (dotkey, '.'))) { sublen = dot - dotkey; } else { sublen = strlen (dotkey); } if (_bson_iter_find_with_len (iter, dotkey, (int)sublen)) { if (!dot) { *descendant = *iter; return true; } if (BSON_ITER_HOLDS_DOCUMENT (iter) || BSON_ITER_HOLDS_ARRAY (iter)) { if (bson_iter_recurse (iter, &tmp)) { return bson_iter_find_descendant (&tmp, dot + 1, descendant); } } } return false; } /* *-------------------------------------------------------------------------- * * bson_iter_key -- * * Retrieves the key of the current field. The resulting key is valid * while @iter is valid. * * Returns: * A string that should not be modified or freed. * * Side effects: * None. * *-------------------------------------------------------------------------- */ const char * bson_iter_key (const bson_iter_t *iter) /* IN */ { BSON_ASSERT (iter); return bson_iter_key_unsafe (iter); } /* *-------------------------------------------------------------------------- * * bson_iter_type -- * * Retrieves the type of the current field. It may be useful to check * the type using the BSON_ITER_HOLDS_*() macros. * * Returns: * A bson_type_t. * * Side effects: * None. * *-------------------------------------------------------------------------- */ bson_type_t bson_iter_type (const bson_iter_t *iter) /* IN */ { BSON_ASSERT (iter); BSON_ASSERT (iter->raw); BSON_ASSERT (iter->len); return bson_iter_type_unsafe (iter); } /* *-------------------------------------------------------------------------- * * bson_iter_next -- * * Advances @iter to the next field of the underlying BSON document. * If all fields have been exhausted, then %false is returned. * * It is a programming error to use @iter after this function has * returned false. * * Returns: * true if the iter was advanced to the next record. * otherwise false and @iter should be considered invalid. * * Side effects: * @iter may be invalidated. * *-------------------------------------------------------------------------- */ bool bson_iter_next (bson_iter_t *iter) /* INOUT */ { const uint8_t *data; uint32_t o; unsigned int len; BSON_ASSERT (iter); if (!iter->raw) { return false; } data = iter->raw; len = iter->len; iter->off = iter->next_off; iter->type = iter->off; iter->key = iter->off + 1; iter->d1 = 0; iter->d2 = 0; iter->d3 = 0; iter->d4 = 0; for (o = iter->off + 1; o < len; o++) { if (!data [o]) { iter->d1 = ++o; goto fill_data_fields; } } goto mark_invalid; fill_data_fields: switch (ITER_TYPE (iter)) { case BSON_TYPE_DATE_TIME: case BSON_TYPE_DOUBLE: case BSON_TYPE_INT64: case BSON_TYPE_TIMESTAMP: iter->next_off = o + 8; break; case BSON_TYPE_CODE: case BSON_TYPE_SYMBOL: case BSON_TYPE_UTF8: { uint32_t l; if ((o + 4) >= len) { iter->err_off = o; goto mark_invalid; } iter->d2 = o + 4; memcpy (&l, iter->raw + iter->d1, sizeof (l)); l = BSON_UINT32_FROM_LE (l); if (l > (len - (o + 4))) { iter->err_off = o; goto mark_invalid; } iter->next_off = o + 4 + l; /* * Make sure the string length includes the NUL byte. */ if (BSON_UNLIKELY ((l == 0) || (iter->next_off >= len))) { iter->err_off = o; goto mark_invalid; } /* * Make sure the last byte is a NUL byte. */ if (BSON_UNLIKELY ((iter->raw + iter->d2)[l - 1] != '\0')) { iter->err_off = o + 4 + l - 1; goto mark_invalid; } } break; case BSON_TYPE_BINARY: { bson_subtype_t subtype; uint32_t l; if (o >= (len - 4)) { iter->err_off = o; goto mark_invalid; } iter->d2 = o + 4; iter->d3 = o + 5; memcpy (&l, iter->raw + iter->d1, sizeof (l)); l = BSON_UINT32_FROM_LE (l); if (l >= (len - o)) { iter->err_off = o; goto mark_invalid; } subtype = *(iter->raw + iter->d2); if (subtype == BSON_SUBTYPE_BINARY_DEPRECATED) { if (l < 4) { iter->err_off = o; goto mark_invalid; } } iter->next_off = o + 5 + l; } break; case BSON_TYPE_ARRAY: case BSON_TYPE_DOCUMENT: { uint32_t l; if (o >= (len - 4)) { iter->err_off = o; goto mark_invalid; } memcpy (&l, iter->raw + iter->d1, sizeof (l)); l = BSON_UINT32_FROM_LE (l); if ((l > len) || (l > (len - o))) { iter->err_off = o; goto mark_invalid; } iter->next_off = o + l; } break; case BSON_TYPE_OID: iter->next_off = o + 12; break; case BSON_TYPE_BOOL: iter->next_off = o + 1; break; case BSON_TYPE_REGEX: { bool eor = false; bool eoo = false; for (; o < len; o++) { if (!data [o]) { iter->d2 = ++o; eor = true; break; } } if (!eor) { iter->err_off = iter->next_off; goto mark_invalid; } for (; o < len; o++) { if (!data [o]) { eoo = true; break; } } if (!eoo) { iter->err_off = iter->next_off; goto mark_invalid; } iter->next_off = o + 1; } break; case BSON_TYPE_DBPOINTER: { uint32_t l; if (o >= (len - 4)) { iter->err_off = o; goto mark_invalid; } iter->d2 = o + 4; memcpy (&l, iter->raw + iter->d1, sizeof (l)); l = BSON_UINT32_FROM_LE (l); if ((l > len) || (l > (len - o))) { iter->err_off = o; goto mark_invalid; } iter->d3 = o + 4 + l; iter->next_off = o + 4 + l + 12; } break; case BSON_TYPE_CODEWSCOPE: { uint32_t l; uint32_t doclen; if ((len < 19) || (o >= (len - 14))) { iter->err_off = o; goto mark_invalid; } iter->d2 = o + 4; iter->d3 = o + 8; memcpy (&l, iter->raw + iter->d1, sizeof (l)); l = BSON_UINT32_FROM_LE (l); if ((l < 14) || (l >= (len - o))) { iter->err_off = o; goto mark_invalid; } iter->next_off = o + l; if (iter->next_off >= len) { iter->err_off = o; goto mark_invalid; } memcpy (&l, iter->raw + iter->d2, sizeof (l)); l = BSON_UINT32_FROM_LE (l); if (l >= (len - o - 4 - 4)) { iter->err_off = o; goto mark_invalid; } if ((o + 4 + 4 + l + 4) >= iter->next_off) { iter->err_off = o + 4; goto mark_invalid; } iter->d4 = o + 4 + 4 + l; memcpy (&doclen, iter->raw + iter->d4, sizeof (doclen)); doclen = BSON_UINT32_FROM_LE (doclen); if ((o + 4 + 4 + l + doclen) != iter->next_off) { iter->err_off = o + 4 + 4 + l; goto mark_invalid; } } break; case BSON_TYPE_INT32: iter->next_off = o + 4; break; case BSON_TYPE_MAXKEY: case BSON_TYPE_MINKEY: case BSON_TYPE_NULL: case BSON_TYPE_UNDEFINED: iter->d1 = -1; iter->next_off = o; break; case BSON_TYPE_EOD: default: iter->err_off = o; goto mark_invalid; } /* * Check to see if any of the field locations would overflow the * current BSON buffer. If so, set the error location to the offset * of where the field starts. */ if (iter->next_off >= len) { iter->err_off = o; goto mark_invalid; } iter->err_off = 0; return true; mark_invalid: iter->raw = NULL; iter->len = 0; iter->next_off = 0; return false; } /* *-------------------------------------------------------------------------- * * bson_iter_binary -- * * Retrieves the BSON_TYPE_BINARY field. The subtype is stored in * @subtype. The length of @binary in bytes is stored in @binary_len. * * @binary should not be modified or freed and is only valid while * @iter is on the current field. * * Parameters: * @iter: A bson_iter_t * @subtype: A location for the binary subtype. * @binary_len: A location for the length of @binary. * @binary: A location for a pointer to the binary data. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void bson_iter_binary (const bson_iter_t *iter, /* IN */ bson_subtype_t *subtype, /* OUT */ uint32_t *binary_len, /* OUT */ const uint8_t **binary) /* OUT */ { bson_subtype_t backup; BSON_ASSERT (iter); BSON_ASSERT (!binary || binary_len); if (ITER_TYPE (iter) == BSON_TYPE_BINARY) { if (!subtype) { subtype = &backup; } *subtype = (bson_subtype_t) *(iter->raw + iter->d2); if (binary) { memcpy (binary_len, (iter->raw + iter->d1), sizeof (*binary_len)); *binary_len = BSON_UINT32_FROM_LE (*binary_len); *binary = iter->raw + iter->d3; if (*subtype == BSON_SUBTYPE_BINARY_DEPRECATED) { *binary_len -= sizeof (int32_t); *binary += sizeof (int32_t); } } return; } if (binary) { *binary = NULL; } if (binary_len) { *binary_len = 0; } if (subtype) { *subtype = BSON_SUBTYPE_BINARY; } } /* *-------------------------------------------------------------------------- * * bson_iter_bool -- * * Retrieves the current field of type BSON_TYPE_BOOL. * * Returns: * true or false, dependent on bson document. * * Side effects: * None. * *-------------------------------------------------------------------------- */ bool bson_iter_bool (const bson_iter_t *iter) /* IN */ { BSON_ASSERT (iter); if (ITER_TYPE (iter) == BSON_TYPE_BOOL) { return bson_iter_bool_unsafe (iter); } return false; } /* *-------------------------------------------------------------------------- * * bson_iter_as_bool -- * * If @iter is on a boolean field, returns the boolean. If it is on a * non-boolean field such as int32, int64, or double, it will convert * the value to a boolean. * * Zero is false, and non-zero is true. * * Returns: * true or false, dependent on field type. * * Side effects: * None. * *-------------------------------------------------------------------------- */ bool bson_iter_as_bool (const bson_iter_t *iter) /* IN */ { BSON_ASSERT (iter); switch ((int)ITER_TYPE (iter)) { case BSON_TYPE_BOOL: return bson_iter_bool (iter); case BSON_TYPE_DOUBLE: return !(bson_iter_double (iter) == 0.0); case BSON_TYPE_INT64: return !(bson_iter_int64 (iter) == 0); case BSON_TYPE_INT32: return !(bson_iter_int32 (iter) == 0); case BSON_TYPE_UTF8: return true; case BSON_TYPE_NULL: case BSON_TYPE_UNDEFINED: return false; default: return true; } } /* *-------------------------------------------------------------------------- * * bson_iter_double -- * * Retrieves the current field of type BSON_TYPE_DOUBLE. * * Returns: * A double. * * Side effects: * None. * *-------------------------------------------------------------------------- */ double bson_iter_double (const bson_iter_t *iter) /* IN */ { BSON_ASSERT (iter); if (ITER_TYPE (iter) == BSON_TYPE_DOUBLE) { return bson_iter_double_unsafe (iter); } return 0; } /* *-------------------------------------------------------------------------- * * bson_iter_int32 -- * * Retrieves the value of the field of type BSON_TYPE_INT32. * * Returns: * A 32-bit signed integer. * * Side effects: * None. * *-------------------------------------------------------------------------- */ int32_t bson_iter_int32 (const bson_iter_t *iter) /* IN */ { BSON_ASSERT (iter); if (ITER_TYPE (iter) == BSON_TYPE_INT32) { return bson_iter_int32_unsafe (iter); } return 0; } /* *-------------------------------------------------------------------------- * * bson_iter_int64 -- * * Retrieves a 64-bit signed integer for the current BSON_TYPE_INT64 * field. * * Returns: * A 64-bit signed integer. * * Side effects: * None. * *-------------------------------------------------------------------------- */ int64_t bson_iter_int64 (const bson_iter_t *iter) /* IN */ { BSON_ASSERT (iter); if (ITER_TYPE (iter) == BSON_TYPE_INT64) { return bson_iter_int64_unsafe (iter); } return 0; } /* *-------------------------------------------------------------------------- * * bson_iter_as_int64 -- * * If @iter is not an int64 field, it will try to convert the value to * an int64. Such field types include: * * - bool * - double * - int32 * * Returns: * An int64_t. * * Side effects: * None. * *-------------------------------------------------------------------------- */ int64_t bson_iter_as_int64 (const bson_iter_t *iter) /* IN */ { BSON_ASSERT (iter); switch ((int)ITER_TYPE (iter)) { case BSON_TYPE_BOOL: return (int64_t)bson_iter_bool (iter); case BSON_TYPE_DOUBLE: return (int64_t)bson_iter_double (iter); case BSON_TYPE_INT64: return bson_iter_int64 (iter); case BSON_TYPE_INT32: return (int64_t)bson_iter_int32 (iter); default: return 0; } } /* *-------------------------------------------------------------------------- * * bson_iter_oid -- * * Retrieves the current field of type %BSON_TYPE_OID. The result is * valid while @iter is valid. * * Returns: * A bson_oid_t that should not be modified or freed. * * Side effects: * None. * *-------------------------------------------------------------------------- */ const bson_oid_t * bson_iter_oid (const bson_iter_t *iter) /* IN */ { BSON_ASSERT (iter); if (ITER_TYPE (iter) == BSON_TYPE_OID) { return bson_iter_oid_unsafe (iter); } return NULL; } /* *-------------------------------------------------------------------------- * * bson_iter_regex -- * * Fetches the current field from the iter which should be of type * BSON_TYPE_REGEX. * * Returns: * Regex from @iter. This should not be modified or freed. * * Side effects: * None. * *-------------------------------------------------------------------------- */ const char * bson_iter_regex (const bson_iter_t *iter, /* IN */ const char **options) /* IN */ { const char *ret = NULL; const char *ret_options = NULL; BSON_ASSERT (iter); if (ITER_TYPE (iter) == BSON_TYPE_REGEX) { ret = (const char *)(iter->raw + iter->d1); ret_options = (const char *)(iter->raw + iter->d2); } if (options) { *options = ret_options; } return ret; } /* *-------------------------------------------------------------------------- * * bson_iter_utf8 -- * * Retrieves the current field of type %BSON_TYPE_UTF8 as a UTF-8 * encoded string. * * Parameters: * @iter: A bson_iter_t. * @length: A location for the length of the string. * * Returns: * A string that should not be modified or freed. * * Side effects: * @length will be set to the result strings length if non-NULL. * *-------------------------------------------------------------------------- */ const char * bson_iter_utf8 (const bson_iter_t *iter, /* IN */ uint32_t *length) /* OUT */ { BSON_ASSERT (iter); if (ITER_TYPE (iter) == BSON_TYPE_UTF8) { if (length) { *length = bson_iter_utf8_len_unsafe (iter); } return (const char *)(iter->raw + iter->d2); } if (length) { *length = 0; } return NULL; } /* *-------------------------------------------------------------------------- * * bson_iter_dup_utf8 -- * * Copies the current UTF-8 element into a newly allocated string. The * string should be freed using bson_free() when the caller is * finished with it. * * Returns: * A newly allocated char* that should be freed with bson_free(). * * Side effects: * @length will be set to the result strings length if non-NULL. * *-------------------------------------------------------------------------- */ char * bson_iter_dup_utf8 (const bson_iter_t *iter, /* IN */ uint32_t *length) /* OUT */ { uint32_t local_length = 0; const char *str; char *ret = NULL; BSON_ASSERT (iter); if ((str = bson_iter_utf8 (iter, &local_length))) { ret = bson_malloc0 (local_length + 1); memcpy (ret, str, local_length); ret[local_length] = '\0'; } if (length) { *length = local_length; } return ret; } /* *-------------------------------------------------------------------------- * * bson_iter_code -- * * Retrieves the current field of type %BSON_TYPE_CODE. The length of * the resulting string is stored in @length. * * Parameters: * @iter: A bson_iter_t. * @length: A location for the code length. * * Returns: * A NUL-terminated string containing the code which should not be * modified or freed. * * Side effects: * None. * *-------------------------------------------------------------------------- */ const char * bson_iter_code (const bson_iter_t *iter, /* IN */ uint32_t *length) /* OUT */ { BSON_ASSERT (iter); if (ITER_TYPE (iter) == BSON_TYPE_CODE) { if (length) { *length = bson_iter_utf8_len_unsafe (iter); } return (const char *)(iter->raw + iter->d2); } if (length) { *length = 0; } return NULL; } /* *-------------------------------------------------------------------------- * * bson_iter_codewscope -- * * Similar to bson_iter_code() but with a scope associated encoded as * a BSON document. @scope should not be modified or freed. It is * valid while @iter is valid. * * Parameters: * @iter: A #bson_iter_t. * @length: A location for the length of resulting string. * @scope_len: A location for the length of @scope. * @scope: A location for the scope encoded as BSON. * * Returns: * A NUL-terminated string that should not be modified or freed. * * Side effects: * @length is set to the resulting string length in bytes. * @scope_len is set to the length of @scope in bytes. * @scope is set to the scope documents buffer which can be * turned into a bson document with bson_init_static(). * *-------------------------------------------------------------------------- */ const char * bson_iter_codewscope (const bson_iter_t *iter, /* IN */ uint32_t *length, /* OUT */ uint32_t *scope_len, /* OUT */ const uint8_t **scope) /* OUT */ { uint32_t len; BSON_ASSERT (iter); if (ITER_TYPE (iter) == BSON_TYPE_CODEWSCOPE) { if (length) { memcpy (&len, iter->raw + iter->d2, sizeof (len)); *length = BSON_UINT32_FROM_LE (len) - 1; } memcpy (&len, iter->raw + iter->d4, sizeof (len)); *scope_len = BSON_UINT32_FROM_LE (len); *scope = iter->raw + iter->d4; return (const char *)(iter->raw + iter->d3); } if (length) { *length = 0; } if (scope_len) { *scope_len = 0; } if (scope) { *scope = NULL; } return NULL; } /* *-------------------------------------------------------------------------- * * bson_iter_dbpointer -- * * Retrieves a BSON_TYPE_DBPOINTER field. @collection_len will be set * to the length of the collection name. The collection name will be * placed into @collection. The oid will be placed into @oid. * * @collection and @oid should not be modified. * * Parameters: * @iter: A #bson_iter_t. * @collection_len: A location for the length of @collection. * @collection: A location for the collection name. * @oid: A location for the oid. * * Returns: * None. * * Side effects: * @collection_len is set to the length of @collection in bytes * excluding the null byte. * @collection is set to the collection name, including a terminating * null byte. * @oid is initialized with the oid. * *-------------------------------------------------------------------------- */ void bson_iter_dbpointer (const bson_iter_t *iter, /* IN */ uint32_t *collection_len, /* OUT */ const char **collection, /* OUT */ const bson_oid_t **oid) /* OUT */ { BSON_ASSERT (iter); if (collection) { *collection = NULL; } if (oid) { *oid = NULL; } if (ITER_TYPE (iter) == BSON_TYPE_DBPOINTER) { if (collection_len) { memcpy (collection_len, (iter->raw + iter->d1), sizeof (*collection_len)); *collection_len = BSON_UINT32_FROM_LE (*collection_len); if ((*collection_len) > 0) { (*collection_len)--; } } if (collection) { *collection = (const char *)(iter->raw + iter->d2); } if (oid) { *oid = (const bson_oid_t *)(iter->raw + iter->d3); } } } /* *-------------------------------------------------------------------------- * * bson_iter_symbol -- * * Retrieves the symbol of the current field of type BSON_TYPE_SYMBOL. * * Parameters: * @iter: A bson_iter_t. * @length: A location for the length of the symbol. * * Returns: * A string containing the symbol as UTF-8. The value should not be * modified or freed. * * Side effects: * @length is set to the resulting strings length in bytes, * excluding the null byte. * *-------------------------------------------------------------------------- */ const char * bson_iter_symbol (const bson_iter_t *iter, /* IN */ uint32_t *length) /* OUT */ { const char *ret = NULL; uint32_t ret_length = 0; BSON_ASSERT (iter); if (ITER_TYPE (iter) == BSON_TYPE_SYMBOL) { ret = (const char *)(iter->raw + iter->d2); ret_length = bson_iter_utf8_len_unsafe (iter); } if (length) { *length = ret_length; } return ret; } /* *-------------------------------------------------------------------------- * * bson_iter_date_time -- * * Fetches the number of milliseconds elapsed since the UNIX epoch. * This value can be negative as times before 1970 are valid. * * Returns: * A signed 64-bit integer containing the number of milliseconds. * * Side effects: * None. * *-------------------------------------------------------------------------- */ int64_t bson_iter_date_time (const bson_iter_t *iter) /* IN */ { BSON_ASSERT (iter); if (ITER_TYPE (iter) == BSON_TYPE_DATE_TIME) { return bson_iter_int64_unsafe (iter); } return 0; } /* *-------------------------------------------------------------------------- * * bson_iter_time_t -- * * Retrieves the current field of type BSON_TYPE_DATE_TIME as a * time_t. * * Returns: * A #time_t of the number of seconds since UNIX epoch in UTC. * * Side effects: * None. * *-------------------------------------------------------------------------- */ time_t bson_iter_time_t (const bson_iter_t *iter) /* IN */ { BSON_ASSERT (iter); if (ITER_TYPE (iter) == BSON_TYPE_DATE_TIME) { return bson_iter_time_t_unsafe (iter); } return 0; } /* *-------------------------------------------------------------------------- * * bson_iter_timestamp -- * * Fetches the current field if it is a BSON_TYPE_TIMESTAMP. * * Parameters: * @iter: A #bson_iter_t. * @timestamp: a location for the timestamp. * @increment: A location for the increment. * * Returns: * None. * * Side effects: * @timestamp is initialized. * @increment is initialized. * *-------------------------------------------------------------------------- */ void bson_iter_timestamp (const bson_iter_t *iter, /* IN */ uint32_t *timestamp, /* OUT */ uint32_t *increment) /* OUT */ { uint64_t encoded; uint32_t ret_timestamp = 0; uint32_t ret_increment = 0; BSON_ASSERT (iter); if (ITER_TYPE (iter) == BSON_TYPE_TIMESTAMP) { memcpy (&encoded, iter->raw + iter->d1, sizeof (encoded)); encoded = BSON_UINT64_FROM_LE (encoded); ret_timestamp = (encoded >> 32) & 0xFFFFFFFF; ret_increment = encoded & 0xFFFFFFFF; } if (timestamp) { *timestamp = ret_timestamp; } if (increment) { *increment = ret_increment; } } /* *-------------------------------------------------------------------------- * * bson_iter_timeval -- * * Retrieves the current field of type BSON_TYPE_DATE_TIME and stores * it into the struct timeval provided. tv->tv_sec is set to the * number of seconds since the UNIX epoch in UTC. * * Since BSON_TYPE_DATE_TIME does not support fractions of a second, * tv->tv_usec will always be set to zero. * * Returns: * None. * * Side effects: * @tv is initialized. * *-------------------------------------------------------------------------- */ void bson_iter_timeval (const bson_iter_t *iter, /* IN */ struct timeval *tv) /* OUT */ { BSON_ASSERT (iter); if (ITER_TYPE (iter) == BSON_TYPE_DATE_TIME) { bson_iter_timeval_unsafe (iter, tv); return; } memset (tv, 0, sizeof *tv); } /** * bson_iter_document: * @iter: a bson_iter_t. * @document_len: A location for the document length. * @document: A location for a pointer to the document buffer. * */ /* *-------------------------------------------------------------------------- * * bson_iter_document -- * * Retrieves the data to the document BSON structure and stores the * length of the document buffer in @document_len and the document * buffer in @document. * * If you would like to iterate over the child contents, you might * consider creating a bson_t on the stack such as the following. It * allows you to call functions taking a const bson_t* only. * * bson_t b; * uint32_t len; * const uint8_t *data; * * bson_iter_document(iter, &len, &data); * * if (bson_init_static (&b, data, len)) { * ... * } * * There is no need to cleanup the bson_t structure as no data can be * modified in the process of its use (as it is static/const). * * Returns: * None. * * Side effects: * @document_len is initialized. * @document is initialized. * *-------------------------------------------------------------------------- */ void bson_iter_document (const bson_iter_t *iter, /* IN */ uint32_t *document_len, /* OUT */ const uint8_t **document) /* OUT */ { BSON_ASSERT (iter); BSON_ASSERT (document_len); BSON_ASSERT (document); *document = NULL; *document_len = 0; if (ITER_TYPE (iter) == BSON_TYPE_DOCUMENT) { memcpy (document_len, (iter->raw + iter->d1), sizeof (*document_len)); *document_len = BSON_UINT32_FROM_LE (*document_len); *document = (iter->raw + iter->d1); } } /** * bson_iter_array: * @iter: a #bson_iter_t. * @array_len: A location for the array length. * @array: A location for a pointer to the array buffer. */ /* *-------------------------------------------------------------------------- * * bson_iter_array -- * * Retrieves the data to the array BSON structure and stores the * length of the array buffer in @array_len and the array buffer in * @array. * * If you would like to iterate over the child contents, you might * consider creating a bson_t on the stack such as the following. It * allows you to call functions taking a const bson_t* only. * * bson_t b; * uint32_t len; * const uint8_t *data; * * bson_iter_array (iter, &len, &data); * * if (bson_init_static (&b, data, len)) { * ... * } * * There is no need to cleanup the #bson_t structure as no data can be * modified in the process of its use. * * Returns: * None. * * Side effects: * @array_len is initialized. * @array is initialized. * *-------------------------------------------------------------------------- */ void bson_iter_array (const bson_iter_t *iter, /* IN */ uint32_t *array_len, /* OUT */ const uint8_t **array) /* OUT */ { BSON_ASSERT (iter); BSON_ASSERT (array_len); BSON_ASSERT (array); *array = NULL; *array_len = 0; if (ITER_TYPE (iter) == BSON_TYPE_ARRAY) { memcpy (array_len, (iter->raw + iter->d1), sizeof (*array_len)); *array_len = BSON_UINT32_FROM_LE (*array_len); *array = (iter->raw + iter->d1); } } #define VISIT_FIELD(name) visitor->visit_##name && visitor->visit_##name #define VISIT_AFTER VISIT_FIELD (after) #define VISIT_BEFORE VISIT_FIELD (before) #define VISIT_CORRUPT if (visitor->visit_corrupt) visitor->visit_corrupt #define VISIT_DOUBLE VISIT_FIELD (double) #define VISIT_UTF8 VISIT_FIELD (utf8) #define VISIT_DOCUMENT VISIT_FIELD (document) #define VISIT_ARRAY VISIT_FIELD (array) #define VISIT_BINARY VISIT_FIELD (binary) #define VISIT_UNDEFINED VISIT_FIELD (undefined) #define VISIT_OID VISIT_FIELD (oid) #define VISIT_BOOL VISIT_FIELD (bool) #define VISIT_DATE_TIME VISIT_FIELD (date_time) #define VISIT_NULL VISIT_FIELD (null) #define VISIT_REGEX VISIT_FIELD (regex) #define VISIT_DBPOINTER VISIT_FIELD (dbpointer) #define VISIT_CODE VISIT_FIELD (code) #define VISIT_SYMBOL VISIT_FIELD (symbol) #define VISIT_CODEWSCOPE VISIT_FIELD (codewscope) #define VISIT_INT32 VISIT_FIELD (int32) #define VISIT_TIMESTAMP VISIT_FIELD (timestamp) #define VISIT_INT64 VISIT_FIELD (int64) #define VISIT_MAXKEY VISIT_FIELD (maxkey) #define VISIT_MINKEY VISIT_FIELD (minkey) /** * bson_iter_visit_all: * @iter: A #bson_iter_t. * @visitor: A #bson_visitor_t containing the visitors. * @data: User data for @visitor data parameters. * * * Returns: true if the visitor was pre-maturely ended; otherwise false. */ /* *-------------------------------------------------------------------------- * * bson_iter_visit_all -- * * Visits all fields forward from the current position of @iter. For * each field found a function in @visitor will be called. Typically * you will use this immediately after initializing a bson_iter_t. * * bson_iter_init (&iter, b); * bson_iter_visit_all (&iter, my_visitor, NULL); * * @iter will no longer be valid after this function has executed and * will need to be reinitialized if intending to reuse. * * Returns: * true if successfully visited all fields or callback requested * early termination, otherwise false. * * Side effects: * None. * *-------------------------------------------------------------------------- */ bool bson_iter_visit_all (bson_iter_t *iter, /* INOUT */ const bson_visitor_t *visitor, /* IN */ void *data) /* IN */ { const char *key; BSON_ASSERT (iter); BSON_ASSERT (visitor); while (bson_iter_next (iter)) { key = bson_iter_key_unsafe (iter); if (*key && !bson_utf8_validate (key, strlen (key), false)) { iter->err_off = iter->off; return true; } if (VISIT_BEFORE (iter, key, data)) { return true; } switch (bson_iter_type (iter)) { case BSON_TYPE_DOUBLE: if (VISIT_DOUBLE (iter, key, bson_iter_double (iter), data)) { return true; } break; case BSON_TYPE_UTF8: { uint32_t utf8_len; const char *utf8; utf8 = bson_iter_utf8 (iter, &utf8_len); if (!bson_utf8_validate (utf8, utf8_len, true)) { iter->err_off = iter->off; return true; } if (VISIT_UTF8 (iter, key, utf8_len, utf8, data)) { return true; } } break; case BSON_TYPE_DOCUMENT: { const uint8_t *docbuf = NULL; uint32_t doclen = 0; bson_t b; bson_iter_document (iter, &doclen, &docbuf); if (bson_init_static (&b, docbuf, doclen) && VISIT_DOCUMENT (iter, key, &b, data)) { return true; } } break; case BSON_TYPE_ARRAY: { const uint8_t *docbuf = NULL; uint32_t doclen = 0; bson_t b; bson_iter_array (iter, &doclen, &docbuf); if (bson_init_static (&b, docbuf, doclen) && VISIT_ARRAY (iter, key, &b, data)) { return true; } } break; case BSON_TYPE_BINARY: { const uint8_t *binary = NULL; bson_subtype_t subtype = BSON_SUBTYPE_BINARY; uint32_t binary_len = 0; bson_iter_binary (iter, &subtype, &binary_len, &binary); if (VISIT_BINARY (iter, key, subtype, binary_len, binary, data)) { return true; } } break; case BSON_TYPE_UNDEFINED: if (VISIT_UNDEFINED (iter, key, data)) { return true; } break; case BSON_TYPE_OID: if (VISIT_OID (iter, key, bson_iter_oid (iter), data)) { return true; } break; case BSON_TYPE_BOOL: if (VISIT_BOOL (iter, key, bson_iter_bool (iter), data)) { return true; } break; case BSON_TYPE_DATE_TIME: if (VISIT_DATE_TIME (iter, key, bson_iter_date_time (iter), data)) { return true; } break; case BSON_TYPE_NULL: if (VISIT_NULL (iter, key, data)) { return true; } break; case BSON_TYPE_REGEX: { const char *regex = NULL; const char *options = NULL; regex = bson_iter_regex (iter, &options); if (VISIT_REGEX (iter, key, regex, options, data)) { return true; } } break; case BSON_TYPE_DBPOINTER: { uint32_t collection_len = 0; const char *collection = NULL; const bson_oid_t *oid = NULL; bson_iter_dbpointer (iter, &collection_len, &collection, &oid); if (VISIT_DBPOINTER (iter, key, collection_len, collection, oid, data)) { return true; } } break; case BSON_TYPE_CODE: { uint32_t code_len; const char *code; code = bson_iter_code (iter, &code_len); if (VISIT_CODE (iter, key, code_len, code, data)) { return true; } } break; case BSON_TYPE_SYMBOL: { uint32_t symbol_len; const char *symbol; symbol = bson_iter_symbol (iter, &symbol_len); if (VISIT_SYMBOL (iter, key, symbol_len, symbol, data)) { return true; } } break; case BSON_TYPE_CODEWSCOPE: { uint32_t length = 0; const char *code; const uint8_t *docbuf = NULL; uint32_t doclen = 0; bson_t b; code = bson_iter_codewscope (iter, &length, &doclen, &docbuf); if (bson_init_static (&b, docbuf, doclen) && VISIT_CODEWSCOPE (iter, key, length, code, &b, data)) { return true; } } break; case BSON_TYPE_INT32: if (VISIT_INT32 (iter, key, bson_iter_int32 (iter), data)) { return true; } break; case BSON_TYPE_TIMESTAMP: { uint32_t timestamp; uint32_t increment; bson_iter_timestamp (iter, ×tamp, &increment); if (VISIT_TIMESTAMP (iter, key, timestamp, increment, data)) { return true; } } break; case BSON_TYPE_INT64: if (VISIT_INT64 (iter, key, bson_iter_int64 (iter), data)) { return true; } break; case BSON_TYPE_MAXKEY: if (VISIT_MAXKEY (iter, bson_iter_key_unsafe (iter), data)) { return true; } break; case BSON_TYPE_MINKEY: if (VISIT_MINKEY (iter, bson_iter_key_unsafe (iter), data)) { return true; } break; case BSON_TYPE_EOD: default: break; } if (VISIT_AFTER (iter, bson_iter_key_unsafe (iter), data)) { return true; } } if (iter->err_off) { VISIT_CORRUPT (iter, data); } #undef VISIT_FIELD return false; } /* *-------------------------------------------------------------------------- * * bson_iter_overwrite_bool -- * * Overwrites the current BSON_TYPE_BOOLEAN field with a new value. * This is performed in-place and therefore no keys are moved. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void bson_iter_overwrite_bool (bson_iter_t *iter, /* IN */ bool value) /* IN */ { BSON_ASSERT (iter); value = !!value; if (ITER_TYPE (iter) == BSON_TYPE_BOOL) { memcpy ((void *)(iter->raw + iter->d1), &value, 1); } } /* *-------------------------------------------------------------------------- * * bson_iter_overwrite_int32 -- * * Overwrites the current BSON_TYPE_INT32 field with a new value. * This is performed in-place and therefore no keys are moved. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void bson_iter_overwrite_int32 (bson_iter_t *iter, /* IN */ int32_t value) /* IN */ { BSON_ASSERT (iter); if (ITER_TYPE (iter) == BSON_TYPE_INT32) { #if BSON_BYTE_ORDER != BSON_LITTLE_ENDIAN value = BSON_UINT32_TO_LE (value); #endif memcpy ((void *)(iter->raw + iter->d1), &value, sizeof (value)); } } /* *-------------------------------------------------------------------------- * * bson_iter_overwrite_int64 -- * * Overwrites the current BSON_TYPE_INT64 field with a new value. * This is performed in-place and therefore no keys are moved. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void bson_iter_overwrite_int64 (bson_iter_t *iter, /* IN */ int64_t value) /* IN */ { BSON_ASSERT (iter); if (ITER_TYPE (iter) == BSON_TYPE_INT64) { #if BSON_BYTE_ORDER != BSON_LITTLE_ENDIAN value = BSON_UINT64_TO_LE (value); #endif memcpy ((void *)(iter->raw + iter->d1), &value, sizeof (value)); } } /* *-------------------------------------------------------------------------- * * bson_iter_overwrite_double -- * * Overwrites the current BSON_TYPE_DOUBLE field with a new value. * This is performed in-place and therefore no keys are moved. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void bson_iter_overwrite_double (bson_iter_t *iter, /* IN */ double value) /* IN */ { BSON_ASSERT (iter); if (ITER_TYPE (iter) == BSON_TYPE_DOUBLE) { value = BSON_DOUBLE_TO_LE (value); memcpy ((void *)(iter->raw + iter->d1), &value, sizeof (value)); } } /* *-------------------------------------------------------------------------- * * bson_iter_value -- * * Retrieves a bson_value_t containing the boxed value of the current * element. The result of this function valid until the state of * iter has been changed (through the use of bson_iter_next()). * * Returns: * A bson_value_t that should not be modified or freed. If you need * to hold on to the value, use bson_value_copy(). * * Side effects: * None. * *-------------------------------------------------------------------------- */ const bson_value_t * bson_iter_value (bson_iter_t *iter) /* IN */ { bson_value_t *value; BSON_ASSERT (iter); value = &iter->value; value->value_type = ITER_TYPE (iter); switch (value->value_type) { case BSON_TYPE_DOUBLE: value->value.v_double = bson_iter_double (iter); break; case BSON_TYPE_UTF8: value->value.v_utf8.str = (char *)bson_iter_utf8 (iter, &value->value.v_utf8.len); break; case BSON_TYPE_DOCUMENT: bson_iter_document (iter, &value->value.v_doc.data_len, (const uint8_t **)&value->value.v_doc.data); break; case BSON_TYPE_ARRAY: bson_iter_array (iter, &value->value.v_doc.data_len, (const uint8_t **)&value->value.v_doc.data); break; case BSON_TYPE_BINARY: bson_iter_binary (iter, &value->value.v_binary.subtype, &value->value.v_binary.data_len, (const uint8_t **)&value->value.v_binary.data); break; case BSON_TYPE_OID: bson_oid_copy (bson_iter_oid (iter), &value->value.v_oid); break; case BSON_TYPE_BOOL: value->value.v_bool = bson_iter_bool (iter); break; case BSON_TYPE_DATE_TIME: value->value.v_datetime = bson_iter_date_time (iter); break; case BSON_TYPE_REGEX: value->value.v_regex.regex = (char *)bson_iter_regex ( iter, (const char **)&value->value.v_regex.options); break; case BSON_TYPE_DBPOINTER: { const bson_oid_t *oid; bson_iter_dbpointer (iter, &value->value.v_dbpointer.collection_len, (const char **)&value->value.v_dbpointer.collection, &oid); bson_oid_copy (oid, &value->value.v_dbpointer.oid); break; } case BSON_TYPE_CODE: value->value.v_code.code = (char *)bson_iter_code ( iter, &value->value.v_code.code_len); break; case BSON_TYPE_SYMBOL: value->value.v_symbol.symbol = (char *)bson_iter_symbol ( iter, &value->value.v_symbol.len); break; case BSON_TYPE_CODEWSCOPE: value->value.v_codewscope.code = (char *)bson_iter_codewscope ( iter, &value->value.v_codewscope.code_len, &value->value.v_codewscope.scope_len, (const uint8_t **)&value->value.v_codewscope.scope_data); break; case BSON_TYPE_INT32: value->value.v_int32 = bson_iter_int32 (iter); break; case BSON_TYPE_TIMESTAMP: bson_iter_timestamp (iter, &value->value.v_timestamp.timestamp, &value->value.v_timestamp.increment); break; case BSON_TYPE_INT64: value->value.v_int64 = bson_iter_int64 (iter); break; case BSON_TYPE_NULL: case BSON_TYPE_UNDEFINED: case BSON_TYPE_MAXKEY: case BSON_TYPE_MINKEY: break; case BSON_TYPE_EOD: default: return NULL; } return value; } mongodb-1.1.5/src/libbson/src/bson/bson-iter.h0000664000175000017500000002550112673034026021033 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef BSON_ITER_H #define BSON_ITER_H #if !defined (BSON_INSIDE) && !defined (BSON_COMPILATION) # error "Only can be included directly." #endif #include "bson.h" #include "bson-endian.h" #include "bson-macros.h" #include "bson-types.h" BSON_BEGIN_DECLS #define BSON_ITER_HOLDS_DOUBLE(iter) \ (bson_iter_type ((iter)) == BSON_TYPE_DOUBLE) #define BSON_ITER_HOLDS_UTF8(iter) \ (bson_iter_type ((iter)) == BSON_TYPE_UTF8) #define BSON_ITER_HOLDS_DOCUMENT(iter) \ (bson_iter_type ((iter)) == BSON_TYPE_DOCUMENT) #define BSON_ITER_HOLDS_ARRAY(iter) \ (bson_iter_type ((iter)) == BSON_TYPE_ARRAY) #define BSON_ITER_HOLDS_BINARY(iter) \ (bson_iter_type ((iter)) == BSON_TYPE_BINARY) #define BSON_ITER_HOLDS_UNDEFINED(iter) \ (bson_iter_type ((iter)) == BSON_TYPE_UNDEFINED) #define BSON_ITER_HOLDS_OID(iter) \ (bson_iter_type ((iter)) == BSON_TYPE_OID) #define BSON_ITER_HOLDS_BOOL(iter) \ (bson_iter_type ((iter)) == BSON_TYPE_BOOL) #define BSON_ITER_HOLDS_DATE_TIME(iter) \ (bson_iter_type ((iter)) == BSON_TYPE_DATE_TIME) #define BSON_ITER_HOLDS_NULL(iter) \ (bson_iter_type ((iter)) == BSON_TYPE_NULL) #define BSON_ITER_HOLDS_REGEX(iter) \ (bson_iter_type ((iter)) == BSON_TYPE_REGEX) #define BSON_ITER_HOLDS_DBPOINTER(iter) \ (bson_iter_type ((iter)) == BSON_TYPE_DBPOINTER) #define BSON_ITER_HOLDS_CODE(iter) \ (bson_iter_type ((iter)) == BSON_TYPE_CODE) #define BSON_ITER_HOLDS_SYMBOL(iter) \ (bson_iter_type ((iter)) == BSON_TYPE_SYMBOL) #define BSON_ITER_HOLDS_CODEWSCOPE(iter) \ (bson_iter_type ((iter)) == BSON_TYPE_CODEWSCOPE) #define BSON_ITER_HOLDS_INT32(iter) \ (bson_iter_type ((iter)) == BSON_TYPE_INT32) #define BSON_ITER_HOLDS_TIMESTAMP(iter) \ (bson_iter_type ((iter)) == BSON_TYPE_TIMESTAMP) #define BSON_ITER_HOLDS_INT64(iter) \ (bson_iter_type ((iter)) == BSON_TYPE_INT64) #define BSON_ITER_HOLDS_MAXKEY(iter) \ (bson_iter_type ((iter)) == BSON_TYPE_MAXKEY) #define BSON_ITER_HOLDS_MINKEY(iter) \ (bson_iter_type ((iter)) == BSON_TYPE_MINKEY) #define BSON_ITER_IS_KEY(iter, key) \ (0 == strcmp ((key), bson_iter_key ((iter)))) const bson_value_t * bson_iter_value (bson_iter_t *iter); /** * bson_iter_utf8_len_unsafe: * @iter: a bson_iter_t. * * Returns the length of a string currently pointed to by @iter. This performs * no validation so the is responsible for knowing the BSON is valid. Calling * bson_validate() is one way to do this ahead of time. */ static BSON_INLINE uint32_t bson_iter_utf8_len_unsafe (const bson_iter_t *iter) { int32_t val; memcpy (&val, iter->raw + iter->d1, sizeof (val)); val = BSON_UINT32_FROM_LE (val); return BSON_MAX (0, val - 1); } void bson_iter_array (const bson_iter_t *iter, uint32_t *array_len, const uint8_t **array); void bson_iter_binary (const bson_iter_t *iter, bson_subtype_t *subtype, uint32_t *binary_len, const uint8_t **binary); const char * bson_iter_code (const bson_iter_t *iter, uint32_t *length); /** * bson_iter_code_unsafe: * @iter: A bson_iter_t. * @length: A location for the length of the resulting string. * * Like bson_iter_code() but performs no integrity checks. * * Returns: A string that should not be modified or freed. */ static BSON_INLINE const char * bson_iter_code_unsafe (const bson_iter_t *iter, uint32_t *length) { *length = bson_iter_utf8_len_unsafe (iter); return (const char *)(iter->raw + iter->d2); } const char * bson_iter_codewscope (const bson_iter_t *iter, uint32_t *length, uint32_t *scope_len, const uint8_t **scope); void bson_iter_dbpointer (const bson_iter_t *iter, uint32_t *collection_len, const char **collection, const bson_oid_t **oid); void bson_iter_document (const bson_iter_t *iter, uint32_t *document_len, const uint8_t **document); double bson_iter_double (const bson_iter_t *iter); /** * bson_iter_double_unsafe: * @iter: A bson_iter_t. * * Similar to bson_iter_double() but does not perform an integrity checking. * * Returns: A double. */ static BSON_INLINE double bson_iter_double_unsafe (const bson_iter_t *iter) { double val; memcpy (&val, iter->raw + iter->d1, sizeof (val)); return BSON_DOUBLE_FROM_LE (val); } bool bson_iter_init (bson_iter_t *iter, const bson_t *bson); bool bson_iter_init_find (bson_iter_t *iter, const bson_t *bson, const char *key); bool bson_iter_init_find_case (bson_iter_t *iter, const bson_t *bson, const char *key); int32_t bson_iter_int32 (const bson_iter_t *iter); /** * bson_iter_int32_unsafe: * @iter: A bson_iter_t. * * Similar to bson_iter_int32() but with no integrity checking. * * Returns: A 32-bit signed integer. */ static BSON_INLINE int32_t bson_iter_int32_unsafe (const bson_iter_t *iter) { int32_t val; memcpy (&val, iter->raw + iter->d1, sizeof (val)); return BSON_UINT32_FROM_LE (val); } int64_t bson_iter_int64 (const bson_iter_t *iter); int64_t bson_iter_as_int64 (const bson_iter_t *iter); /** * bson_iter_int64_unsafe: * @iter: a bson_iter_t. * * Similar to bson_iter_int64() but without integrity checking. * * Returns: A 64-bit signed integer. */ static BSON_INLINE int64_t bson_iter_int64_unsafe (const bson_iter_t *iter) { int64_t val; memcpy (&val, iter->raw + iter->d1, sizeof (val)); return BSON_UINT64_FROM_LE (val); } bool bson_iter_find (bson_iter_t *iter, const char *key); bool bson_iter_find_case (bson_iter_t *iter, const char *key); bool bson_iter_find_descendant (bson_iter_t *iter, const char *dotkey, bson_iter_t *descendant); bool bson_iter_next (bson_iter_t *iter); const bson_oid_t * bson_iter_oid (const bson_iter_t *iter); /** * bson_iter_oid_unsafe: * @iter: A #bson_iter_t. * * Similar to bson_iter_oid() but performs no integrity checks. * * Returns: A #bson_oid_t that should not be modified or freed. */ static BSON_INLINE const bson_oid_t * bson_iter_oid_unsafe (const bson_iter_t *iter) { return (const bson_oid_t *)(iter->raw + iter->d1); } const char * bson_iter_key (const bson_iter_t *iter); /** * bson_iter_key_unsafe: * @iter: A bson_iter_t. * * Similar to bson_iter_key() but performs no integrity checking. * * Returns: A string that should not be modified or freed. */ static BSON_INLINE const char * bson_iter_key_unsafe (const bson_iter_t *iter) { return (const char *)(iter->raw + iter->key); } const char * bson_iter_utf8 (const bson_iter_t *iter, uint32_t *length); /** * bson_iter_utf8_unsafe: * * Similar to bson_iter_utf8() but performs no integrity checking. * * Returns: A string that should not be modified or freed. */ static BSON_INLINE const char * bson_iter_utf8_unsafe (const bson_iter_t *iter, size_t *length) { *length = bson_iter_utf8_len_unsafe (iter); return (const char *)(iter->raw + iter->d2); } char * bson_iter_dup_utf8 (const bson_iter_t *iter, uint32_t *length); int64_t bson_iter_date_time (const bson_iter_t *iter); time_t bson_iter_time_t (const bson_iter_t *iter); /** * bson_iter_time_t_unsafe: * @iter: A bson_iter_t. * * Similar to bson_iter_time_t() but performs no integrity checking. * * Returns: A time_t containing the number of seconds since UNIX epoch * in UTC. */ static BSON_INLINE time_t bson_iter_time_t_unsafe (const bson_iter_t *iter) { return (time_t)(bson_iter_int64_unsafe (iter) / 1000UL); } void bson_iter_timeval (const bson_iter_t *iter, struct timeval *tv); /** * bson_iter_timeval_unsafe: * @iter: A bson_iter_t. * @tv: A struct timeval. * * Similar to bson_iter_timeval() but performs no integrity checking. */ static BSON_INLINE void bson_iter_timeval_unsafe (const bson_iter_t *iter, struct timeval *tv) { int64_t value = bson_iter_int64_unsafe (iter); #ifdef BSON_OS_WIN32 tv->tv_sec = (long) (value / 1000); #else tv->tv_sec = (suseconds_t) (value / 1000); #endif tv->tv_usec = (value % 1000) * 1000; } void bson_iter_timestamp (const bson_iter_t *iter, uint32_t *timestamp, uint32_t *increment); bool bson_iter_bool (const bson_iter_t *iter); /** * bson_iter_bool_unsafe: * @iter: A bson_iter_t. * * Similar to bson_iter_bool() but performs no integrity checking. * * Returns: true or false. */ static BSON_INLINE bool bson_iter_bool_unsafe (const bson_iter_t *iter) { char val; memcpy (&val, iter->raw + iter->d1, 1); return !!val; } bool bson_iter_as_bool (const bson_iter_t *iter); const char * bson_iter_regex (const bson_iter_t *iter, const char **options); const char * bson_iter_symbol (const bson_iter_t *iter, uint32_t *length); bson_type_t bson_iter_type (const bson_iter_t *iter); /** * bson_iter_type_unsafe: * @iter: A bson_iter_t. * * Similar to bson_iter_type() but performs no integrity checking. * * Returns: A bson_type_t. */ static BSON_INLINE bson_type_t bson_iter_type_unsafe (const bson_iter_t *iter) { return (bson_type_t) (iter->raw + iter->type) [0]; } bool bson_iter_recurse (const bson_iter_t *iter, bson_iter_t *child); void bson_iter_overwrite_int32 (bson_iter_t *iter, int32_t value); void bson_iter_overwrite_int64 (bson_iter_t *iter, int64_t value); void bson_iter_overwrite_double (bson_iter_t *iter, double value); void bson_iter_overwrite_bool (bson_iter_t *iter, bool value); bool bson_iter_visit_all (bson_iter_t *iter, const bson_visitor_t *visitor, void *data); BSON_END_DECLS #endif /* BSON_ITER_H */ mongodb-1.1.5/src/libbson/src/bson/bson-json.c0000664000175000017500000011220412673034026021031 0ustar jmikolajmikola/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include "bson.h" #include "bson-config.h" #include "bson-json.h" #include "bson-iso8601-private.h" #include "b64_pton.h" #include #include #ifdef _WIN32 # include # include #endif #define STACK_MAX 100 #define BSON_JSON_DEFAULT_BUF_SIZE (1 << 14) typedef enum { BSON_JSON_REGULAR, BSON_JSON_DONE, BSON_JSON_ERROR, BSON_JSON_IN_START_MAP, BSON_JSON_IN_BSON_TYPE, BSON_JSON_IN_BSON_TYPE_DATE_NUMBERLONG, BSON_JSON_IN_BSON_TYPE_DATE_ENDMAP, BSON_JSON_IN_BSON_TYPE_TIMESTAMP_STARTMAP, BSON_JSON_IN_BSON_TYPE_TIMESTAMP_VALUES, BSON_JSON_IN_BSON_TYPE_TIMESTAMP_ENDMAP, } bson_json_read_state_t; typedef enum { BSON_JSON_LF_REGEX, BSON_JSON_LF_OPTIONS, BSON_JSON_LF_OID, BSON_JSON_LF_BINARY, BSON_JSON_LF_TYPE, BSON_JSON_LF_DATE, BSON_JSON_LF_TIMESTAMP_T, BSON_JSON_LF_TIMESTAMP_I, BSON_JSON_LF_UNDEFINED, BSON_JSON_LF_MINKEY, BSON_JSON_LF_MAXKEY, BSON_JSON_LF_INT64, } bson_json_read_bson_state_t; typedef struct { uint8_t *buf; size_t n_bytes; size_t len; } bson_json_buf_t; typedef struct { int i; bool is_array; bson_t bson; } bson_json_stack_frame_t; typedef union { struct { bool has_regex; bool has_options; } regex; struct { bool has_oid; bson_oid_t oid; } oid; struct { bool has_binary; bool has_subtype; bson_subtype_t type; } binary; struct { bool has_date; int64_t date; } date; struct { bool has_t; bool has_i; uint32_t t; uint32_t i; } timestamp; struct { bool has_undefined; } undefined; struct { bool has_minkey; } minkey; struct { bool has_maxkey; } maxkey; struct { int64_t value; } v_int64; } bson_json_bson_data_t; typedef struct { bson_t *bson; bson_json_stack_frame_t stack[STACK_MAX]; int n; const char *key; bson_json_buf_t key_buf; bson_json_read_state_t read_state; bson_json_read_bson_state_t bson_state; bson_type_t bson_type; bson_json_buf_t bson_type_buf [3]; bson_json_bson_data_t bson_type_data; bool known_bson_type; } bson_json_reader_bson_t; typedef struct { void *data; bson_json_reader_cb cb; bson_json_destroy_cb dcb; uint8_t *buf; size_t buf_size; size_t bytes_read; size_t bytes_parsed; bool all_whitespace; } bson_json_reader_producer_t; struct _bson_json_reader_t { bson_json_reader_producer_t producer; bson_json_reader_bson_t bson; yajl_handle yh; bson_error_t *error; }; typedef struct { int fd; bool do_close; } bson_json_reader_handle_fd_t; static void * bson_yajl_malloc_func (void *ctx, size_t sz) { return bson_malloc (sz); } static void bson_yajl_free_func (void *ctx, void *ptr) { bson_free (ptr); } static void * bson_yajl_realloc_func (void *ctx, void *ptr, size_t sz) { return bson_realloc (ptr, sz); } static yajl_alloc_funcs gYajlAllocFuncs = { bson_yajl_malloc_func, bson_yajl_realloc_func, bson_yajl_free_func, }; static void _noop (void) { } #define STACK_ELE(_delta, _name) (bson->stack[(_delta) + bson->n]._name) #define STACK_BSON(_delta) \ (((_delta) + bson->n) == 0 ? bson->bson : &STACK_ELE (_delta, bson)) #define STACK_BSON_PARENT STACK_BSON (-1) #define STACK_BSON_CHILD STACK_BSON (0) #define STACK_I STACK_ELE (0, i) #define STACK_IS_ARRAY STACK_ELE (0, is_array) #define STACK_PUSH_ARRAY(statement) \ do { \ if (bson->n >= (STACK_MAX - 1)) { return 0; } \ bson->n++; \ STACK_I = 0; \ STACK_IS_ARRAY = 1; \ if (bson->n != 0) { \ statement; \ } \ } while (0) #define STACK_PUSH_DOC(statement) \ do { \ if (bson->n >= (STACK_MAX - 1)) { return 0; } \ bson->n++; \ STACK_IS_ARRAY = 0; \ if (bson->n != 0) { \ statement; \ } \ } while (0) #define STACK_POP_ARRAY(statement) \ do { \ if (!STACK_IS_ARRAY) { return 0; } \ if (bson->n < 0) { return 0; } \ if (bson->n > 0) { \ statement; \ } \ bson->n--; \ } while (0) #define STACK_POP_DOC(statement) \ do { \ if (STACK_IS_ARRAY) { return 0; } \ if (bson->n < 0) { return 0; } \ if (bson->n > 0) { \ statement; \ } \ bson->n--; \ } while (0) #define BASIC_YAJL_CB_PREAMBLE \ const char *key; \ size_t len; \ bson_json_reader_t *reader = (bson_json_reader_t *)_ctx; \ bson_json_reader_bson_t *bson = &reader->bson; \ _bson_json_read_fixup_key (bson); \ key = bson->key; \ len = bson->key_buf.len; #define BASIC_YAJL_CB_BAIL_IF_NOT_NORMAL(_type) \ if (bson->read_state != BSON_JSON_REGULAR) { \ _bson_json_read_set_error (reader, "Invalid read of %s in state %d", \ (_type), bson->read_state); \ return 0; \ } else if (! key) { \ _bson_json_read_set_error (reader, "Invalid read of %s without key in state %d", \ (_type), bson->read_state); \ return 0; \ } #define HANDLE_OPTION(_key, _type, _state) \ (len == strlen (_key) && strncmp ((const char *)val, (_key), len) == 0) { \ if (bson->known_bson_type && bson->bson_type != (_type)) { \ _bson_json_read_set_error (reader, \ "Invalid key %s. Looking for values for %d", \ (_key), bson->bson_type); \ return 0; \ } \ bson->bson_type = (_type); \ bson->bson_state = (_state); \ } static bool _bson_json_all_whitespace (const char *utf8) { bool all_whitespace = true; if (utf8) { for (; *utf8; utf8 = bson_utf8_next_char (utf8)) { if (!isspace (bson_utf8_get_char (utf8))) { all_whitespace = false; break; } } } return all_whitespace; } static void _bson_json_read_set_error (bson_json_reader_t *reader, const char *fmt, ...) BSON_GNUC_PRINTF (2, 3); static void _bson_json_read_set_error (bson_json_reader_t *reader, /* IN */ const char *fmt, /* IN */ ...) { va_list ap; if (reader->error) { reader->error->domain = BSON_ERROR_JSON; reader->error->code = BSON_JSON_ERROR_READ_INVALID_PARAM; va_start (ap, fmt); bson_vsnprintf (reader->error->message, sizeof reader->error->message, fmt, ap); va_end (ap); reader->error->message [sizeof reader->error->message - 1] = '\0'; } reader->bson.read_state = BSON_JSON_ERROR; } static void _bson_json_buf_ensure (bson_json_buf_t *buf, /* IN */ size_t len) /* IN */ { if (buf->n_bytes < len) { bson_free (buf->buf); buf->n_bytes = bson_next_power_of_two (len); buf->buf = bson_malloc (buf->n_bytes); } } static void _bson_json_read_fixup_key (bson_json_reader_bson_t *bson) /* IN */ { if (bson->n >= 0 && STACK_IS_ARRAY) { _bson_json_buf_ensure (&bson->key_buf, 12); bson->key_buf.len = bson_uint32_to_string (STACK_I, &bson->key, (char *)bson->key_buf.buf, 12); STACK_I++; } } static void _bson_json_buf_set (bson_json_buf_t *buf, /* IN */ const void *from, /* IN */ size_t len, /* IN */ bool trailing_null) /* IN */ { if (trailing_null) { _bson_json_buf_ensure (buf, len + 1); } else { _bson_json_buf_ensure (buf, len); } memcpy (buf->buf, from, len); if (trailing_null) { buf->buf[len] = '\0'; } buf->len = len; } static int _bson_json_read_null (void *_ctx) { BASIC_YAJL_CB_PREAMBLE; BASIC_YAJL_CB_BAIL_IF_NOT_NORMAL ("null"); bson_append_null (STACK_BSON_CHILD, key, (int)len); return 1; } static int _bson_json_read_boolean (void *_ctx, /* IN */ int val) /* IN */ { BASIC_YAJL_CB_PREAMBLE; if (bson->read_state == BSON_JSON_IN_BSON_TYPE && bson->bson_state == BSON_JSON_LF_UNDEFINED) { bson->bson_type_data.undefined.has_undefined = true; return 1; } BASIC_YAJL_CB_BAIL_IF_NOT_NORMAL ("boolean"); bson_append_bool (STACK_BSON_CHILD, key, (int)len, val); return 1; } static int _bson_json_read_integer (void *_ctx, /* IN */ int64_t val) /* IN */ { bson_json_read_state_t rs; bson_json_read_bson_state_t bs; BASIC_YAJL_CB_PREAMBLE; rs = bson->read_state; bs = bson->bson_state; if (rs == BSON_JSON_REGULAR) { BASIC_YAJL_CB_BAIL_IF_NOT_NORMAL ("integer"); if (val <= INT32_MAX) { bson_append_int32 (STACK_BSON_CHILD, key, (int)len, (int)val); } else { bson_append_int64 (STACK_BSON_CHILD, key, (int)len, val); } } else if (rs == BSON_JSON_IN_BSON_TYPE || rs == BSON_JSON_IN_BSON_TYPE_TIMESTAMP_VALUES) { switch (bs) { case BSON_JSON_LF_DATE: bson->bson_type_data.date.has_date = true; bson->bson_type_data.date.date = val; break; case BSON_JSON_LF_TIMESTAMP_T: bson->bson_type_data.timestamp.has_t = true; bson->bson_type_data.timestamp.t = (uint32_t)val; break; case BSON_JSON_LF_TIMESTAMP_I: bson->bson_type_data.timestamp.has_i = true; bson->bson_type_data.timestamp.i = (uint32_t)val; break; case BSON_JSON_LF_MINKEY: bson->bson_type_data.minkey.has_minkey = true; break; case BSON_JSON_LF_MAXKEY: bson->bson_type_data.maxkey.has_maxkey = true; break; case BSON_JSON_LF_REGEX: case BSON_JSON_LF_OPTIONS: case BSON_JSON_LF_OID: case BSON_JSON_LF_BINARY: case BSON_JSON_LF_TYPE: case BSON_JSON_LF_UNDEFINED: case BSON_JSON_LF_INT64: default: _bson_json_read_set_error (reader, "Invalid special type for integer read %d", bs); return 0; } } else { _bson_json_read_set_error (reader, "Invalid state for integer read %d", rs); return 0; } return 1; } static int _bson_json_read_double (void *_ctx, /* IN */ double val) /* IN */ { BASIC_YAJL_CB_PREAMBLE; BASIC_YAJL_CB_BAIL_IF_NOT_NORMAL ("double"); bson_append_double (STACK_BSON_CHILD, key, (int)len, val); return 1; } static int _bson_json_read_string (void *_ctx, /* IN */ const unsigned char *val, /* IN */ size_t vlen) /* IN */ { bson_json_read_state_t rs; bson_json_read_bson_state_t bs; BASIC_YAJL_CB_PREAMBLE; rs = bson->read_state; bs = bson->bson_state; if (rs == BSON_JSON_REGULAR) { BASIC_YAJL_CB_BAIL_IF_NOT_NORMAL ("string"); bson_append_utf8 (STACK_BSON_CHILD, key, (int)len, (const char *)val, (int)vlen); } else if (rs == BSON_JSON_IN_BSON_TYPE || rs == BSON_JSON_IN_BSON_TYPE_TIMESTAMP_VALUES || rs == BSON_JSON_IN_BSON_TYPE_DATE_NUMBERLONG) { const char *val_w_null; _bson_json_buf_set (&bson->bson_type_buf[2], val, vlen, true); val_w_null = (const char *)bson->bson_type_buf[2].buf; switch (bs) { case BSON_JSON_LF_REGEX: bson->bson_type_data.regex.has_regex = true; _bson_json_buf_set (&bson->bson_type_buf[0], val, vlen, true); break; case BSON_JSON_LF_OPTIONS: bson->bson_type_data.regex.has_options = true; _bson_json_buf_set (&bson->bson_type_buf[1], val, vlen, true); break; case BSON_JSON_LF_OID: if (vlen != 24) { goto BAD_PARSE; } bson->bson_type_data.oid.has_oid = true; bson_oid_init_from_string (&bson->bson_type_data.oid.oid, val_w_null); break; case BSON_JSON_LF_TYPE: bson->bson_type_data.binary.has_subtype = true; #ifdef _MSC_VER # define SSCANF sscanf_s #else # define SSCANF sscanf #endif if (SSCANF (val_w_null, "%02x", &bson->bson_type_data.binary.type) != 1) { goto BAD_PARSE; } #undef SSCANF break; case BSON_JSON_LF_BINARY: { /* TODO: error handling for pton */ int binary_len; bson->bson_type_data.binary.has_binary = true; binary_len = b64_pton (val_w_null, NULL, 0); _bson_json_buf_ensure (&bson->bson_type_buf[0], binary_len + 1); b64_pton ((char *)bson->bson_type_buf[2].buf, bson->bson_type_buf[0].buf, binary_len + 1); bson->bson_type_buf[0].len = binary_len; break; } case BSON_JSON_LF_INT64: { int64_t v64; char *endptr = NULL; errno = 0; v64 = bson_ascii_strtoll ((const char *)val, &endptr, 10); if (((v64 == INT64_MIN) || (v64 == INT64_MAX)) && (errno == ERANGE)) { goto BAD_PARSE; } if (endptr != ((const char *)val + vlen)) { goto BAD_PARSE; } if (bson->read_state == BSON_JSON_IN_BSON_TYPE) { bson->bson_type_data.v_int64.value = v64; } else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_DATE_NUMBERLONG) { bson->bson_type_data.date.has_date = true; bson->bson_type_data.date.date = v64; } else { goto BAD_PARSE; } } break; case BSON_JSON_LF_DATE: { int64_t v64; if (!_bson_iso8601_date_parse ((char *)val, (int)vlen, &v64)) { _bson_json_read_set_error (reader, "Could not parse \"%s\" as a date", val_w_null); return 0; } else { bson->bson_type_data.date.has_date = true; bson->bson_type_data.date.date = v64; } } break; case BSON_JSON_LF_TIMESTAMP_T: case BSON_JSON_LF_TIMESTAMP_I: case BSON_JSON_LF_UNDEFINED: case BSON_JSON_LF_MINKEY: case BSON_JSON_LF_MAXKEY: default: goto BAD_PARSE; } return 1; BAD_PARSE: _bson_json_read_set_error (reader, "Invalid input string %s, looking for %d", val_w_null, bs); return 0; } else { _bson_json_read_set_error (reader, "Invalid state to look for string %d", rs); return 0; } return 1; } static int _bson_json_read_start_map (void *_ctx) /* IN */ { BASIC_YAJL_CB_PREAMBLE; if (bson->read_state == BSON_JSON_IN_BSON_TYPE && bson->bson_state == BSON_JSON_LF_DATE) { bson->read_state = BSON_JSON_IN_BSON_TYPE_DATE_NUMBERLONG; } else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_TIMESTAMP_STARTMAP) { bson->read_state = BSON_JSON_IN_BSON_TYPE_TIMESTAMP_VALUES; } else { bson->read_state = BSON_JSON_IN_START_MAP; } /* silence some warnings */ (void)len; (void)key; return 1; } static bool _is_known_key (const char *key, size_t len) { bool ret; #define IS_KEY(k) (len == strlen(k) && (0 == memcmp (k, key, len))) ret = (IS_KEY ("$regex") || IS_KEY ("$options") || IS_KEY ("$oid") || IS_KEY ("$binary") || IS_KEY ("$type") || IS_KEY ("$date") || IS_KEY ("$undefined") || IS_KEY ("$maxKey") || IS_KEY ("$minKey") || IS_KEY ("$timestamp") || IS_KEY ("$numberLong")); #undef IS_KEY return ret; } static int _bson_json_read_map_key (void *_ctx, /* IN */ const uint8_t *val, /* IN */ size_t len) /* IN */ { bson_json_reader_t *reader = (bson_json_reader_t *)_ctx; bson_json_reader_bson_t *bson = &reader->bson; if (bson->read_state == BSON_JSON_IN_START_MAP) { if (len > 0 && val[0] == '$' && _is_known_key ((const char *)val, len)) { bson->read_state = BSON_JSON_IN_BSON_TYPE; bson->bson_type = (bson_type_t) 0; memset (&bson->bson_type_data, 0, sizeof bson->bson_type_data); } else { bson->read_state = BSON_JSON_REGULAR; STACK_PUSH_DOC (bson_append_document_begin (STACK_BSON_PARENT, bson->key, (int)bson->key_buf.len, STACK_BSON_CHILD)); } } if (bson->read_state == BSON_JSON_IN_BSON_TYPE) { if HANDLE_OPTION ("$regex", BSON_TYPE_REGEX, BSON_JSON_LF_REGEX) else if HANDLE_OPTION ("$options", BSON_TYPE_REGEX, BSON_JSON_LF_OPTIONS) else if HANDLE_OPTION ("$oid", BSON_TYPE_OID, BSON_JSON_LF_OID) else if HANDLE_OPTION ("$binary", BSON_TYPE_BINARY, BSON_JSON_LF_BINARY) else if HANDLE_OPTION ("$type", BSON_TYPE_BINARY, BSON_JSON_LF_TYPE) else if HANDLE_OPTION ("$date", BSON_TYPE_DATE_TIME, BSON_JSON_LF_DATE) else if HANDLE_OPTION ("$undefined", BSON_TYPE_UNDEFINED, BSON_JSON_LF_UNDEFINED) else if HANDLE_OPTION ("$minKey", BSON_TYPE_MINKEY, BSON_JSON_LF_MINKEY) else if HANDLE_OPTION ("$maxKey", BSON_TYPE_MAXKEY, BSON_JSON_LF_MAXKEY) else if HANDLE_OPTION ("$numberLong", BSON_TYPE_INT64, BSON_JSON_LF_INT64) else if (len == strlen ("$timestamp") && memcmp (val, "$timestamp", len) == 0) { bson->bson_type = BSON_TYPE_TIMESTAMP; bson->read_state = BSON_JSON_IN_BSON_TYPE_TIMESTAMP_STARTMAP; } else { _bson_json_read_set_error (reader, "Invalid key %s. Looking for values for %d", val, bson->bson_type); return 0; } } else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_DATE_NUMBERLONG) { if HANDLE_OPTION ("$numberLong", BSON_TYPE_DATE_TIME, BSON_JSON_LF_INT64) else { _bson_json_read_set_error (reader, "Invalid key %s. Looking for values for %d", val, bson->bson_type); return 0; } } else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_TIMESTAMP_VALUES) { if HANDLE_OPTION ("t", BSON_TYPE_TIMESTAMP, BSON_JSON_LF_TIMESTAMP_T) else if HANDLE_OPTION ("i", BSON_TYPE_TIMESTAMP, BSON_JSON_LF_TIMESTAMP_I) else { _bson_json_read_set_error (reader, "Invalid key %s. Looking for values for %d", val, bson->bson_type); return 0; } } else { _bson_json_buf_set (&bson->key_buf, val, len, true); bson->key = (const char *)bson->key_buf.buf; } return 1; } static int _bson_json_read_append_binary (bson_json_reader_t *reader, /* IN */ bson_json_reader_bson_t *bson) /* IN */ { if (!bson->bson_type_data.binary.has_binary) { _bson_json_read_set_error (reader, "Missing $binary after $type in BSON_TYPE_BINARY"); } else if (!bson->bson_type_data.binary.has_subtype) { _bson_json_read_set_error (reader, "Missing $type after $binary in BSON_TYPE_BINARY"); } else { return bson_append_binary (STACK_BSON_CHILD, bson->key, (int)bson->key_buf.len, bson->bson_type_data.binary.type, bson->bson_type_buf[0].buf, (uint32_t)bson->bson_type_buf[0].len); } return 0; } static int _bson_json_read_append_regex (bson_json_reader_t *reader, /* IN */ bson_json_reader_bson_t *bson) /* IN */ { char *regex = NULL; char *options = NULL; if (!bson->bson_type_data.regex.has_regex) { _bson_json_read_set_error (reader, "Missing $regex after $options in BSON_TYPE_REGEX"); return 0; } regex = (char *)bson->bson_type_buf[0].buf; if (bson->bson_type_data.regex.has_options) { options = (char *)bson->bson_type_buf[1].buf; } return bson_append_regex (STACK_BSON_CHILD, bson->key, (int)bson->key_buf.len, regex, options); } static int _bson_json_read_append_oid (bson_json_reader_t *reader, /* IN */ bson_json_reader_bson_t *bson) /* IN */ { return bson_append_oid (STACK_BSON_CHILD, bson->key, (int)bson->key_buf.len, &bson->bson_type_data.oid.oid); } static int _bson_json_read_append_date_time (bson_json_reader_t *reader, /* IN */ bson_json_reader_bson_t *bson) /* IN */ { return bson_append_date_time (STACK_BSON_CHILD, bson->key, (int)bson->key_buf.len, bson->bson_type_data.date.date); } static int _bson_json_read_append_timestamp (bson_json_reader_t *reader, /* IN */ bson_json_reader_bson_t *bson) /* IN */ { if (!bson->bson_type_data.timestamp.has_t) { _bson_json_read_set_error (reader, "Missing t after $timestamp in BSON_TYPE_TIMESTAMP"); return 0; } if (!bson->bson_type_data.timestamp.has_i) { _bson_json_read_set_error (reader, "Missing i after $timestamp in BSON_TYPE_TIMESTAMP"); return 0; } return bson_append_timestamp (STACK_BSON_CHILD, bson->key, (int)bson->key_buf.len, bson->bson_type_data.timestamp.t, bson->bson_type_data.timestamp.i); } static int _bson_json_read_end_map (void *_ctx) /* IN */ { bson_json_reader_t *reader = (bson_json_reader_t *)_ctx; bson_json_reader_bson_t *bson = &reader->bson; if (bson->read_state == BSON_JSON_IN_START_MAP) { bson->read_state = BSON_JSON_REGULAR; STACK_PUSH_DOC (bson_append_document_begin (STACK_BSON_PARENT, bson->key, (int)bson->key_buf.len, STACK_BSON_CHILD)); } if (bson->read_state == BSON_JSON_IN_BSON_TYPE) { bson->read_state = BSON_JSON_REGULAR; switch (bson->bson_type) { case BSON_TYPE_REGEX: return _bson_json_read_append_regex (reader, bson); case BSON_TYPE_OID: return _bson_json_read_append_oid (reader, bson); case BSON_TYPE_BINARY: return _bson_json_read_append_binary (reader, bson); case BSON_TYPE_DATE_TIME: return _bson_json_read_append_date_time (reader, bson); case BSON_TYPE_UNDEFINED: return bson_append_undefined (STACK_BSON_CHILD, bson->key, (int)bson->key_buf.len); case BSON_TYPE_MINKEY: return bson_append_minkey (STACK_BSON_CHILD, bson->key, (int)bson->key_buf.len); case BSON_TYPE_MAXKEY: return bson_append_maxkey (STACK_BSON_CHILD, bson->key, (int)bson->key_buf.len); case BSON_TYPE_INT64: return bson_append_int64 (STACK_BSON_CHILD, bson->key, (int)bson->key_buf.len, bson->bson_type_data.v_int64.value); case BSON_TYPE_EOD: case BSON_TYPE_DOUBLE: case BSON_TYPE_UTF8: case BSON_TYPE_DOCUMENT: case BSON_TYPE_ARRAY: case BSON_TYPE_BOOL: case BSON_TYPE_NULL: case BSON_TYPE_CODE: case BSON_TYPE_SYMBOL: case BSON_TYPE_CODEWSCOPE: case BSON_TYPE_INT32: case BSON_TYPE_TIMESTAMP: case BSON_TYPE_DBPOINTER: default: _bson_json_read_set_error (reader, "Unknown type %d", bson->bson_type); return 0; break; } } else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_TIMESTAMP_VALUES) { bson->read_state = BSON_JSON_IN_BSON_TYPE_TIMESTAMP_ENDMAP; return _bson_json_read_append_timestamp (reader, bson); } else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_TIMESTAMP_ENDMAP) { bson->read_state = BSON_JSON_REGULAR; } else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_DATE_NUMBERLONG) { bson->read_state = BSON_JSON_IN_BSON_TYPE_DATE_ENDMAP; return _bson_json_read_append_date_time(reader, bson); } else if (bson->read_state == BSON_JSON_IN_BSON_TYPE_DATE_ENDMAP) { bson->read_state = BSON_JSON_REGULAR; } else if (bson->read_state == BSON_JSON_REGULAR) { STACK_POP_DOC (bson_append_document_end (STACK_BSON_PARENT, STACK_BSON_CHILD)); if (bson->n == -1) { bson->read_state = BSON_JSON_DONE; return 0; } } else { _bson_json_read_set_error (reader, "Invalid state %d", bson->read_state); return 0; } return 1; } static int _bson_json_read_start_array (void *_ctx) /* IN */ { const char *key; size_t len; bson_json_reader_t *reader = (bson_json_reader_t *)_ctx; bson_json_reader_bson_t *bson = &reader->bson; if (bson->n < 0) { STACK_PUSH_ARRAY (_noop ()); } else { _bson_json_read_fixup_key (bson); key = bson->key; len = bson->key_buf.len; BASIC_YAJL_CB_BAIL_IF_NOT_NORMAL ("["); STACK_PUSH_ARRAY (bson_append_array_begin (STACK_BSON_PARENT, key, (int)len, STACK_BSON_CHILD)); } return 1; } static int _bson_json_read_end_array (void *_ctx) /* IN */ { bson_json_reader_t *reader = (bson_json_reader_t *)_ctx; bson_json_reader_bson_t *bson = &reader->bson; if (bson->read_state != BSON_JSON_REGULAR) { _bson_json_read_set_error (reader, "Invalid read of %s in state %d", "]", bson->read_state); return 0; } STACK_POP_ARRAY (bson_append_array_end (STACK_BSON_PARENT, STACK_BSON_CHILD)); if (bson->n == -1) { bson->read_state = BSON_JSON_DONE; return 0; } return 1; } static yajl_callbacks read_cbs = { _bson_json_read_null, _bson_json_read_boolean, _bson_json_read_integer, _bson_json_read_double, NULL, _bson_json_read_string, _bson_json_read_start_map, _bson_json_read_map_key, _bson_json_read_end_map, _bson_json_read_start_array, _bson_json_read_end_array }; static int _bson_json_read_parse_error (bson_json_reader_t *reader, /* IN */ yajl_status ys, /* IN */ bson_error_t *error) /* OUT */ { unsigned char *str; int r; yajl_handle yh = reader->yh; bson_json_reader_bson_t *bson = &reader->bson; bson_json_reader_producer_t *p = &reader->producer; if (ys == yajl_status_client_canceled) { if (bson->read_state == BSON_JSON_DONE) { r = 1; } else { r = -1; } } else if (p->all_whitespace) { r = 0; } else { if (error) { str = yajl_get_error (yh, 1, p->buf + p->bytes_parsed, p->bytes_read - p->bytes_parsed); bson_set_error (error, BSON_ERROR_JSON, BSON_JSON_ERROR_READ_CORRUPT_JS, "%s", str); yajl_free_error (yh, str); } r = -1; } p->bytes_parsed += yajl_get_bytes_consumed (yh); yh->stateStack.used = 0; yajl_bs_push (yh->stateStack, yajl_state_start); return r; } /* *-------------------------------------------------------------------------- * * bson_json_reader_read -- * * Read the next json document from @reader and write its value * into @bson. @bson will be allocated as part of this process. * * @bson MUST be initialized before calling this function as it * will not be initialized automatically. The reasoning for this * is so that you can chain together bson_json_reader_t with * other components like bson_writer_t. * * Returns: * 1 if successful and data was read. * 0 if successful and no data was read. * -1 if there was an error and @error is set. * * Side effects: * @error may be set. * *-------------------------------------------------------------------------- */ int bson_json_reader_read (bson_json_reader_t *reader, /* IN */ bson_t *bson, /* IN */ bson_error_t *error) /* OUT */ { bson_json_reader_producer_t *p; yajl_status ys; yajl_handle yh; ssize_t r; bool read_something = false; int ret = 0; BSON_ASSERT (reader); BSON_ASSERT (bson); p = &reader->producer; yh = reader->yh; reader->bson.bson = bson; reader->bson.n = -1; reader->bson.read_state = BSON_JSON_REGULAR; reader->error = error; reader->producer.all_whitespace = true; for (;; ) { if (!read_something && p->bytes_parsed && (p->bytes_read > p->bytes_parsed)) { r = p->bytes_read - p->bytes_parsed; } else { r = p->cb (p->data, p->buf, p->buf_size - 1); if (r > 0) { p->bytes_read = r; p->bytes_parsed = 0; p->buf[r] = '\0'; } } if (r < 0) { if (error) { bson_set_error (error, BSON_ERROR_JSON, BSON_JSON_ERROR_READ_CB_FAILURE, "reader cb failed"); } ret = -1; goto cleanup; } else if (r == 0) { break; } else { read_something = true; if (p->all_whitespace) { p->all_whitespace = _bson_json_all_whitespace ( (char *)(p->buf + p->bytes_parsed)); } ys = yajl_parse (yh, p->buf + p->bytes_parsed, r); if (ys != yajl_status_ok) { ret = _bson_json_read_parse_error (reader, ys, error); goto cleanup; } } } if (read_something) { ys = yajl_complete_parse (yh); if (ys != yajl_status_ok) { ret = _bson_json_read_parse_error (reader, ys, error); goto cleanup; } } cleanup: return ret; } bson_json_reader_t * bson_json_reader_new (void *data, /* IN */ bson_json_reader_cb cb, /* IN */ bson_json_destroy_cb dcb, /* IN */ bool allow_multiple, /* IN */ size_t buf_size) /* IN */ { bson_json_reader_t *r; bson_json_reader_producer_t *p; r = bson_malloc0 (sizeof *r); p = &r->producer; p->data = data; p->cb = cb; p->dcb = dcb; p->buf_size = buf_size ? buf_size : BSON_JSON_DEFAULT_BUF_SIZE; p->buf = bson_malloc (p->buf_size); r->yh = yajl_alloc (&read_cbs, &gYajlAllocFuncs, r); yajl_config (r->yh, yajl_dont_validate_strings | (allow_multiple ? yajl_allow_multiple_values : 0) , 1); return r; } void bson_json_reader_destroy (bson_json_reader_t *reader) /* IN */ { int i; bson_json_reader_producer_t *p = &reader->producer; bson_json_reader_bson_t *b = &reader->bson; if (reader->producer.dcb) { reader->producer.dcb (reader->producer.data); } bson_free (p->buf); bson_free (b->key_buf.buf); for (i = 0; i < 3; i++) { bson_free (b->bson_type_buf[i].buf); } yajl_free (reader->yh); bson_free (reader); } typedef struct { const uint8_t *data; size_t len; size_t bytes_parsed; } bson_json_data_reader_t; static ssize_t _bson_json_data_reader_cb (void *_ctx, uint8_t *buf, size_t len) { size_t bytes; bson_json_data_reader_t *ctx = (bson_json_data_reader_t *)_ctx; if (!ctx->data) { return -1; } bytes = BSON_MIN (len, ctx->len - ctx->bytes_parsed); memcpy (buf, ctx->data + ctx->bytes_parsed, bytes); ctx->bytes_parsed += bytes; return bytes; } bson_json_reader_t * bson_json_data_reader_new (bool allow_multiple, /* IN */ size_t size) /* IN */ { bson_json_data_reader_t *dr = bson_malloc0 (sizeof *dr); return bson_json_reader_new (dr, &_bson_json_data_reader_cb, &bson_free, allow_multiple, size); } void bson_json_data_reader_ingest (bson_json_reader_t *reader, /* IN */ const uint8_t *data, /* IN */ size_t len) /* IN */ { bson_json_data_reader_t *ctx = (bson_json_data_reader_t *)reader->producer.data; ctx->data = data; ctx->len = len; ctx->bytes_parsed = 0; } bson_t * bson_new_from_json (const uint8_t *data, /* IN */ ssize_t len, /* IN */ bson_error_t *error) /* OUT */ { bson_json_reader_t *reader; bson_t *bson; int r; BSON_ASSERT (data); if (len < 0) { len = (ssize_t)strlen ((const char *)data); } bson = bson_new (); reader = bson_json_data_reader_new (false, BSON_JSON_DEFAULT_BUF_SIZE); bson_json_data_reader_ingest (reader, data, len); r = bson_json_reader_read (reader, bson, error); bson_json_reader_destroy (reader); if (r != 1) { bson_destroy (bson); return NULL; } return bson; } bool bson_init_from_json (bson_t *bson, /* OUT */ const char *data, /* IN */ ssize_t len, /* IN */ bson_error_t *error) /* OUT */ { bson_json_reader_t *reader; int r; BSON_ASSERT (bson); BSON_ASSERT (data); if (len < 0) { len = strlen (data); } bson_init (bson); reader = bson_json_data_reader_new (false, BSON_JSON_DEFAULT_BUF_SIZE); bson_json_data_reader_ingest (reader, (const uint8_t *)data, len); r = bson_json_reader_read (reader, bson, error); bson_json_reader_destroy (reader); if (r != 1) { bson_destroy (bson); return false; } return true; } static void _bson_json_reader_handle_fd_destroy (void *handle) /* IN */ { bson_json_reader_handle_fd_t *fd = handle; if (fd) { if ((fd->fd != -1) && fd->do_close) { #ifdef _WIN32 _close(fd->fd); #else close (fd->fd); #endif } bson_free (fd); } } static ssize_t _bson_json_reader_handle_fd_read (void *handle, /* IN */ uint8_t *buf, /* IN */ size_t len) /* IN */ { bson_json_reader_handle_fd_t *fd = handle; ssize_t ret = -1; if (fd && (fd->fd != -1)) { again: #ifdef BSON_OS_WIN32 ret = _read (fd->fd, buf, (unsigned int)len); #else ret = read (fd->fd, buf, len); #endif if ((ret == -1) && (errno == EAGAIN)) { goto again; } } return ret; } bson_json_reader_t * bson_json_reader_new_from_fd (int fd, /* IN */ bool close_on_destroy) /* IN */ { bson_json_reader_handle_fd_t *handle; BSON_ASSERT (fd != -1); handle = bson_malloc0 (sizeof *handle); handle->fd = fd; handle->do_close = close_on_destroy; return bson_json_reader_new (handle, _bson_json_reader_handle_fd_read, _bson_json_reader_handle_fd_destroy, true, BSON_JSON_DEFAULT_BUF_SIZE); } bson_json_reader_t * bson_json_reader_new_from_file (const char *path, /* IN */ bson_error_t *error) /* OUT */ { char errmsg_buf[BSON_ERROR_BUFFER_SIZE]; char *errmsg; int fd = -1; BSON_ASSERT (path); #ifdef BSON_OS_WIN32 _sopen_s (&fd, path, (_O_RDONLY | _O_BINARY), _SH_DENYNO, _S_IREAD); #else fd = open (path, O_RDONLY); #endif if (fd == -1) { errmsg = bson_strerror_r (errno, errmsg_buf, sizeof errmsg_buf); bson_set_error (error, BSON_ERROR_READER, BSON_ERROR_READER_BADFD, "%s", errmsg); return NULL; } return bson_json_reader_new_from_fd (fd, true); } mongodb-1.1.5/src/libbson/src/bson/bson-json.h0000664000175000017500000000532312673034026021041 0ustar jmikolajmikola/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef BSON_JSON_H #define BSON_JSON_H #if !defined (BSON_INSIDE) && !defined (BSON_COMPILATION) # error "Only can be included directly." #endif #include "bson.h" BSON_BEGIN_DECLS typedef struct _bson_json_reader_t bson_json_reader_t; typedef enum { BSON_JSON_ERROR_READ_CORRUPT_JS = 1, BSON_JSON_ERROR_READ_INVALID_PARAM, BSON_JSON_ERROR_READ_CB_FAILURE, } bson_json_error_code_t; typedef ssize_t (*bson_json_reader_cb) (void *handle, uint8_t *buf, size_t count); typedef void (*bson_json_destroy_cb)(void *handle); bson_json_reader_t *bson_json_reader_new (void *data, bson_json_reader_cb cb, bson_json_destroy_cb dcb, bool allow_multiple, size_t buf_size); bson_json_reader_t *bson_json_reader_new_from_fd (int fd, bool close_on_destroy); bson_json_reader_t *bson_json_reader_new_from_file (const char *filename, bson_error_t *error); void bson_json_reader_destroy (bson_json_reader_t *reader); int bson_json_reader_read (bson_json_reader_t *reader, bson_t *bson, bson_error_t *error); bson_json_reader_t *bson_json_data_reader_new (bool allow_multiple, size_t size); void bson_json_data_reader_ingest (bson_json_reader_t *reader, const uint8_t *data, size_t len); BSON_END_DECLS #endif /* BSON_JSON_H */ mongodb-1.1.5/src/libbson/src/bson/bson-keys.c0000664000175000017500000002222512673034026021036 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include "bson-keys.h" #include "bson-string.h" static const char * gUint32Strs[] = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", "100", "101", "102", "103", "104", "105", "106", "107", "108", "109", "110", "111", "112", "113", "114", "115", "116", "117", "118", "119", "120", "121", "122", "123", "124", "125", "126", "127", "128", "129", "130", "131", "132", "133", "134", "135", "136", "137", "138", "139", "140", "141", "142", "143", "144", "145", "146", "147", "148", "149", "150", "151", "152", "153", "154", "155", "156", "157", "158", "159", "160", "161", "162", "163", "164", "165", "166", "167", "168", "169", "170", "171", "172", "173", "174", "175", "176", "177", "178", "179", "180", "181", "182", "183", "184", "185", "186", "187", "188", "189", "190", "191", "192", "193", "194", "195", "196", "197", "198", "199", "200", "201", "202", "203", "204", "205", "206", "207", "208", "209", "210", "211", "212", "213", "214", "215", "216", "217", "218", "219", "220", "221", "222", "223", "224", "225", "226", "227", "228", "229", "230", "231", "232", "233", "234", "235", "236", "237", "238", "239", "240", "241", "242", "243", "244", "245", "246", "247", "248", "249", "250", "251", "252", "253", "254", "255", "256", "257", "258", "259", "260", "261", "262", "263", "264", "265", "266", "267", "268", "269", "270", "271", "272", "273", "274", "275", "276", "277", "278", "279", "280", "281", "282", "283", "284", "285", "286", "287", "288", "289", "290", "291", "292", "293", "294", "295", "296", "297", "298", "299", "300", "301", "302", "303", "304", "305", "306", "307", "308", "309", "310", "311", "312", "313", "314", "315", "316", "317", "318", "319", "320", "321", "322", "323", "324", "325", "326", "327", "328", "329", "330", "331", "332", "333", "334", "335", "336", "337", "338", "339", "340", "341", "342", "343", "344", "345", "346", "347", "348", "349", "350", "351", "352", "353", "354", "355", "356", "357", "358", "359", "360", "361", "362", "363", "364", "365", "366", "367", "368", "369", "370", "371", "372", "373", "374", "375", "376", "377", "378", "379", "380", "381", "382", "383", "384", "385", "386", "387", "388", "389", "390", "391", "392", "393", "394", "395", "396", "397", "398", "399", "400", "401", "402", "403", "404", "405", "406", "407", "408", "409", "410", "411", "412", "413", "414", "415", "416", "417", "418", "419", "420", "421", "422", "423", "424", "425", "426", "427", "428", "429", "430", "431", "432", "433", "434", "435", "436", "437", "438", "439", "440", "441", "442", "443", "444", "445", "446", "447", "448", "449", "450", "451", "452", "453", "454", "455", "456", "457", "458", "459", "460", "461", "462", "463", "464", "465", "466", "467", "468", "469", "470", "471", "472", "473", "474", "475", "476", "477", "478", "479", "480", "481", "482", "483", "484", "485", "486", "487", "488", "489", "490", "491", "492", "493", "494", "495", "496", "497", "498", "499", "500", "501", "502", "503", "504", "505", "506", "507", "508", "509", "510", "511", "512", "513", "514", "515", "516", "517", "518", "519", "520", "521", "522", "523", "524", "525", "526", "527", "528", "529", "530", "531", "532", "533", "534", "535", "536", "537", "538", "539", "540", "541", "542", "543", "544", "545", "546", "547", "548", "549", "550", "551", "552", "553", "554", "555", "556", "557", "558", "559", "560", "561", "562", "563", "564", "565", "566", "567", "568", "569", "570", "571", "572", "573", "574", "575", "576", "577", "578", "579", "580", "581", "582", "583", "584", "585", "586", "587", "588", "589", "590", "591", "592", "593", "594", "595", "596", "597", "598", "599", "600", "601", "602", "603", "604", "605", "606", "607", "608", "609", "610", "611", "612", "613", "614", "615", "616", "617", "618", "619", "620", "621", "622", "623", "624", "625", "626", "627", "628", "629", "630", "631", "632", "633", "634", "635", "636", "637", "638", "639", "640", "641", "642", "643", "644", "645", "646", "647", "648", "649", "650", "651", "652", "653", "654", "655", "656", "657", "658", "659", "660", "661", "662", "663", "664", "665", "666", "667", "668", "669", "670", "671", "672", "673", "674", "675", "676", "677", "678", "679", "680", "681", "682", "683", "684", "685", "686", "687", "688", "689", "690", "691", "692", "693", "694", "695", "696", "697", "698", "699", "700", "701", "702", "703", "704", "705", "706", "707", "708", "709", "710", "711", "712", "713", "714", "715", "716", "717", "718", "719", "720", "721", "722", "723", "724", "725", "726", "727", "728", "729", "730", "731", "732", "733", "734", "735", "736", "737", "738", "739", "740", "741", "742", "743", "744", "745", "746", "747", "748", "749", "750", "751", "752", "753", "754", "755", "756", "757", "758", "759", "760", "761", "762", "763", "764", "765", "766", "767", "768", "769", "770", "771", "772", "773", "774", "775", "776", "777", "778", "779", "780", "781", "782", "783", "784", "785", "786", "787", "788", "789", "790", "791", "792", "793", "794", "795", "796", "797", "798", "799", "800", "801", "802", "803", "804", "805", "806", "807", "808", "809", "810", "811", "812", "813", "814", "815", "816", "817", "818", "819", "820", "821", "822", "823", "824", "825", "826", "827", "828", "829", "830", "831", "832", "833", "834", "835", "836", "837", "838", "839", "840", "841", "842", "843", "844", "845", "846", "847", "848", "849", "850", "851", "852", "853", "854", "855", "856", "857", "858", "859", "860", "861", "862", "863", "864", "865", "866", "867", "868", "869", "870", "871", "872", "873", "874", "875", "876", "877", "878", "879", "880", "881", "882", "883", "884", "885", "886", "887", "888", "889", "890", "891", "892", "893", "894", "895", "896", "897", "898", "899", "900", "901", "902", "903", "904", "905", "906", "907", "908", "909", "910", "911", "912", "913", "914", "915", "916", "917", "918", "919", "920", "921", "922", "923", "924", "925", "926", "927", "928", "929", "930", "931", "932", "933", "934", "935", "936", "937", "938", "939", "940", "941", "942", "943", "944", "945", "946", "947", "948", "949", "950", "951", "952", "953", "954", "955", "956", "957", "958", "959", "960", "961", "962", "963", "964", "965", "966", "967", "968", "969", "970", "971", "972", "973", "974", "975", "976", "977", "978", "979", "980", "981", "982", "983", "984", "985", "986", "987", "988", "989", "990", "991", "992", "993", "994", "995", "996", "997", "998", "999" }; /* *-------------------------------------------------------------------------- * * bson_uint32_to_string -- * * Converts @value to a string. * * If @value is from 0 to 1000, it will use a constant string in the * data section of the library. * * If not, a string will be formatted using @str and snprintf(). This * is much slower, of course and therefore we try to optimize it out. * * @strptr will always be set. It will either point to @str or a * constant string. You will want to use this as your key. * * Parameters: * @value: A #uint32_t to convert to string. * @strptr: (out): A pointer to the resulting string. * @str: (out): Storage for a string made with snprintf. * @size: Size of @str. * * Returns: * The number of bytes in the resulting string. * * Side effects: * None. * *-------------------------------------------------------------------------- */ size_t bson_uint32_to_string (uint32_t value, /* IN */ const char **strptr, /* OUT */ char *str, /* OUT */ size_t size) /* IN */ { if (value < 1000) { *strptr = gUint32Strs[value]; if (value < 10) { return 1; } else if (value < 100) { return 2; } else { return 3; } } *strptr = str; return bson_snprintf (str, size, "%u", value); } mongodb-1.1.5/src/libbson/src/bson/bson-keys.h0000664000175000017500000000167012673034026021044 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef BSON_KEYS_H #define BSON_KEYS_H #include "bson-macros.h" #include "bson-types.h" BSON_BEGIN_DECLS size_t bson_uint32_to_string (uint32_t value, const char **strptr, char *str, size_t size); BSON_END_DECLS #endif /* BSON_KEYS_H */ mongodb-1.1.5/src/libbson/src/bson/bson-macros.h0000664000175000017500000001275312673034026021361 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef BSON_MACROS_H #define BSON_MACROS_H #if !defined (BSON_INSIDE) && !defined (BSON_COMPILATION) # error "Only can be included directly." #endif #include #include #ifdef __cplusplus # include #endif #include "bson-config.h" #if BSON_OS == 1 # define BSON_OS_UNIX #elif BSON_OS == 2 # define BSON_OS_WIN32 #else # error "Unknown operating system." #endif #ifdef __cplusplus # define BSON_BEGIN_DECLS extern "C" { # define BSON_END_DECLS } #else # define BSON_BEGIN_DECLS # define BSON_END_DECLS #endif #define BSON_GNUC_CHECK_VERSION(major, minor) \ (defined(__GNUC__) && \ ((__GNUC__ > (major)) || \ ((__GNUC__ == (major)) && \ (__GNUC_MINOR__ >= (minor))))) #define BSON_GNUC_IS_VERSION(major, minor) \ (defined(__GNUC__) && \ (__GNUC__ == (major)) && \ (__GNUC_MINOR__ == (minor))) #ifdef _MSC_VER # ifdef BSON_COMPILATION # define BSON_API __declspec(dllexport) # else # define BSON_API __declspec(dllimport) # endif #else # define BSON_API #endif #ifdef MIN # define BSON_MIN MIN #elif defined(__cplusplus) # define BSON_MIN(a, b) ( (std::min)(a, b) ) #elif defined(_MSC_VER) # define BSON_MIN(a, b) ((a) < (b) ? (a) : (b)) #else # define BSON_MIN(a,b) (((a) < (b)) ? (a) : (b)) #endif #ifdef MAX # define BSON_MAX MAX #elif defined(__cplusplus) # define BSON_MAX(a, b) ( (std::max)(a, b) ) #elif defined(_MSC_VER) # define BSON_MAX(a, b) ((a) > (b) ? (a) : (b)) #else # define BSON_MAX(a, b) (((a) > (b)) ? (a) : (b)) #endif #ifdef ABS # define BSON_ABS ABS #else # define BSON_ABS(a) (((a) < 0) ? ((a) * -1) : (a)) #endif #ifdef _MSC_VER # ifdef _WIN64 # define BSON_ALIGN_OF_PTR 8 # else # define BSON_ALIGN_OF_PTR 4 # endif #else # define BSON_ALIGN_OF_PTR (sizeof(void *)) #endif #ifdef BSON_EXTRA_ALIGN # if defined(_MSC_VER) # define BSON_ALIGNED_BEGIN(_N) __declspec (align (_N)) # define BSON_ALIGNED_END(_N) # else # define BSON_ALIGNED_BEGIN(_N) # define BSON_ALIGNED_END(_N) __attribute__((aligned (_N))) # endif #else # if defined(_MSC_VER) # define BSON_ALIGNED_BEGIN(_N) __declspec (align ((_N) > BSON_ALIGN_OF_PTR ? BSON_ALIGN_OF_PTR : (_N) )) # define BSON_ALIGNED_END(_N) # else # define BSON_ALIGNED_BEGIN(_N) # define BSON_ALIGNED_END(_N) __attribute__((aligned ((_N) > BSON_ALIGN_OF_PTR ? BSON_ALIGN_OF_PTR : (_N) ))) # endif #endif #define bson_str_empty(s) (!s[0]) #define bson_str_empty0(s) (!s || !s[0]) #if defined(_WIN32) # define BSON_FUNC __FUNCTION__ #elif defined(__STDC_VERSION__) && __STDC_VERSION__ < 199901L # define BSON_FUNC __FUNCTION__ #else # define BSON_FUNC __func__ #endif #define BSON_ASSERT(test) \ do { \ if (!(BSON_LIKELY(test))) { \ fprintf (stderr, "%s:%d %s(): precondition failed: %s\n", \ __FILE__, __LINE__, BSON_FUNC, #test); \ abort (); \ } \ } while (0) #define BSON_STATIC_ASSERT(s) BSON_STATIC_ASSERT_ (s, __LINE__) #define BSON_STATIC_ASSERT_JOIN(a, b) BSON_STATIC_ASSERT_JOIN2 (a, b) #define BSON_STATIC_ASSERT_JOIN2(a, b) a##b #define BSON_STATIC_ASSERT_(s, l) \ typedef char BSON_STATIC_ASSERT_JOIN (static_assert_test_, \ __LINE__)[(s) ? 1 : -1] #if defined(__GNUC__) # define BSON_GNUC_CONST __attribute__((const)) # define BSON_GNUC_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) #else # define BSON_GNUC_CONST # define BSON_GNUC_WARN_UNUSED_RESULT #endif #if BSON_GNUC_CHECK_VERSION(4, 0) && !defined(_WIN32) # define BSON_GNUC_NULL_TERMINATED __attribute__((sentinel)) # define BSON_GNUC_INTERNAL __attribute__((visibility ("hidden"))) #else # define BSON_GNUC_NULL_TERMINATED # define BSON_GNUC_INTERNAL #endif #if defined(__GNUC__) # define BSON_LIKELY(x) __builtin_expect (!!(x), 1) # define BSON_UNLIKELY(x) __builtin_expect (!!(x), 0) #else # define BSON_LIKELY(v) v # define BSON_UNLIKELY(v) v #endif #if defined(__clang__) # define BSON_GNUC_PRINTF(f, v) __attribute__((format (printf, f, v))) #elif BSON_GNUC_CHECK_VERSION(4, 4) # define BSON_GNUC_PRINTF(f, v) __attribute__((format (gnu_printf, f, v))) #else # define BSON_GNUC_PRINTF(f, v) #endif #if defined(__LP64__) || defined(_LP64) # define BSON_WORD_SIZE 64 #else # define BSON_WORD_SIZE 32 #endif #if defined(_MSC_VER) # define BSON_INLINE __inline #else # define BSON_INLINE __inline__ #endif #ifdef _MSC_VER # define BSON_ENSURE_ARRAY_PARAM_SIZE(_n) # define BSON_TYPEOF decltype #else # define BSON_ENSURE_ARRAY_PARAM_SIZE(_n) static (_n) # define BSON_TYPEOF typeof #endif #if BSON_GNUC_CHECK_VERSION(3, 1) # define BSON_GNUC_DEPRECATED __attribute__((__deprecated__)) #else # define BSON_GNUC_DEPRECATED #endif #if BSON_GNUC_CHECK_VERSION(4, 5) # define BSON_GNUC_DEPRECATED_FOR(f) __attribute__((deprecated("Use " #f " instead"))) #else # define BSON_GNUC_DEPRECATED_FOR(f) BSON_GNUC_DEPRECATED #endif #endif /* BSON_MACROS_H */ mongodb-1.1.5/src/libbson/src/bson/bson-md5.c0000664000175000017500000003175312673034026020556 0ustar jmikolajmikola/* Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved. This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. L. Peter Deutsch ghost@aladdin.com */ /* $Id: md5.c,v 1.6 2002/04/13 19:20:28 lpd Exp $ */ /* Independent implementation of MD5 (RFC 1321). This code implements the MD5 Algorithm defined in RFC 1321, whose text is available at http://www.ietf.org/rfc/rfc1321.txt The code is derived from the text of the RFC, including the test suite (section A.5) but excluding the rest of Appendix A. It does not include any code or documentation that is identified in the RFC as being copyrighted. The original and principal author of md5.c is L. Peter Deutsch . Other authors are noted in the change history that follows (in reverse chronological order): 2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order either statically or dynamically; added missing #include in library. 2002-03-11 lpd Corrected argument list for main(), and added int return type, in test program and T value program. 2002-02-21 lpd Added missing #include in test program. 2000-07-03 lpd Patched to eliminate warnings about "constant is unsigned in ANSI C, signed in traditional"; made test program self-checking. 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5). 1999-05-03 lpd Original version. */ /* * The following MD5 implementation has been modified to use types as * specified in libbson. */ #include "bson-compat.h" #include #include "bson-md5.h" #undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */ #if BSON_BYTE_ORDER == BSON_BIG_ENDIAN # define BYTE_ORDER 1 #else # define BYTE_ORDER -1 #endif #define T_MASK ((uint32_t)~0) #define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87) #define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9) #define T3 0x242070db #define T4 /* 0xc1bdceee */ (T_MASK ^ 0x3e423111) #define T5 /* 0xf57c0faf */ (T_MASK ^ 0x0a83f050) #define T6 0x4787c62a #define T7 /* 0xa8304613 */ (T_MASK ^ 0x57cfb9ec) #define T8 /* 0xfd469501 */ (T_MASK ^ 0x02b96afe) #define T9 0x698098d8 #define T10 /* 0x8b44f7af */ (T_MASK ^ 0x74bb0850) #define T11 /* 0xffff5bb1 */ (T_MASK ^ 0x0000a44e) #define T12 /* 0x895cd7be */ (T_MASK ^ 0x76a32841) #define T13 0x6b901122 #define T14 /* 0xfd987193 */ (T_MASK ^ 0x02678e6c) #define T15 /* 0xa679438e */ (T_MASK ^ 0x5986bc71) #define T16 0x49b40821 #define T17 /* 0xf61e2562 */ (T_MASK ^ 0x09e1da9d) #define T18 /* 0xc040b340 */ (T_MASK ^ 0x3fbf4cbf) #define T19 0x265e5a51 #define T20 /* 0xe9b6c7aa */ (T_MASK ^ 0x16493855) #define T21 /* 0xd62f105d */ (T_MASK ^ 0x29d0efa2) #define T22 0x02441453 #define T23 /* 0xd8a1e681 */ (T_MASK ^ 0x275e197e) #define T24 /* 0xe7d3fbc8 */ (T_MASK ^ 0x182c0437) #define T25 0x21e1cde6 #define T26 /* 0xc33707d6 */ (T_MASK ^ 0x3cc8f829) #define T27 /* 0xf4d50d87 */ (T_MASK ^ 0x0b2af278) #define T28 0x455a14ed #define T29 /* 0xa9e3e905 */ (T_MASK ^ 0x561c16fa) #define T30 /* 0xfcefa3f8 */ (T_MASK ^ 0x03105c07) #define T31 0x676f02d9 #define T32 /* 0x8d2a4c8a */ (T_MASK ^ 0x72d5b375) #define T33 /* 0xfffa3942 */ (T_MASK ^ 0x0005c6bd) #define T34 /* 0x8771f681 */ (T_MASK ^ 0x788e097e) #define T35 0x6d9d6122 #define T36 /* 0xfde5380c */ (T_MASK ^ 0x021ac7f3) #define T37 /* 0xa4beea44 */ (T_MASK ^ 0x5b4115bb) #define T38 0x4bdecfa9 #define T39 /* 0xf6bb4b60 */ (T_MASK ^ 0x0944b49f) #define T40 /* 0xbebfbc70 */ (T_MASK ^ 0x4140438f) #define T41 0x289b7ec6 #define T42 /* 0xeaa127fa */ (T_MASK ^ 0x155ed805) #define T43 /* 0xd4ef3085 */ (T_MASK ^ 0x2b10cf7a) #define T44 0x04881d05 #define T45 /* 0xd9d4d039 */ (T_MASK ^ 0x262b2fc6) #define T46 /* 0xe6db99e5 */ (T_MASK ^ 0x1924661a) #define T47 0x1fa27cf8 #define T48 /* 0xc4ac5665 */ (T_MASK ^ 0x3b53a99a) #define T49 /* 0xf4292244 */ (T_MASK ^ 0x0bd6ddbb) #define T50 0x432aff97 #define T51 /* 0xab9423a7 */ (T_MASK ^ 0x546bdc58) #define T52 /* 0xfc93a039 */ (T_MASK ^ 0x036c5fc6) #define T53 0x655b59c3 #define T54 /* 0x8f0ccc92 */ (T_MASK ^ 0x70f3336d) #define T55 /* 0xffeff47d */ (T_MASK ^ 0x00100b82) #define T56 /* 0x85845dd1 */ (T_MASK ^ 0x7a7ba22e) #define T57 0x6fa87e4f #define T58 /* 0xfe2ce6e0 */ (T_MASK ^ 0x01d3191f) #define T59 /* 0xa3014314 */ (T_MASK ^ 0x5cfebceb) #define T60 0x4e0811a1 #define T61 /* 0xf7537e82 */ (T_MASK ^ 0x08ac817d) #define T62 /* 0xbd3af235 */ (T_MASK ^ 0x42c50dca) #define T63 0x2ad7d2bb #define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e) static void bson_md5_process (bson_md5_t *md5, const uint8_t *data) { uint32_t a = md5->abcd[0]; uint32_t b = md5->abcd[1]; uint32_t c = md5->abcd[2]; uint32_t d = md5->abcd[3]; uint32_t t; #if BYTE_ORDER > 0 /* Define storage only for big-endian CPUs. */ uint32_t X[16]; #else /* Define storage for little-endian or both types of CPUs. */ uint32_t xbuf[16]; const uint32_t *X; #endif { #if BYTE_ORDER == 0 /* * Determine dynamically whether this is a big-endian or * little-endian machine, since we can use a more efficient * algorithm on the latter. */ static const int w = 1; if (*((const uint8_t *)&w)) /* dynamic little-endian */ #endif #if BYTE_ORDER <= 0 /* little-endian */ { /* * On little-endian machines, we can process properly aligned * data without copying it. */ if (!((data - (const uint8_t *)0) & 3)) { /* data are properly aligned */ #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wcast-align" #endif X = (const uint32_t *)data; #ifdef __clang__ #pragma clang diagnostic pop #endif } else { /* not aligned */ memcpy(xbuf, data, sizeof (xbuf)); X = xbuf; } } #endif #if BYTE_ORDER == 0 else /* dynamic big-endian */ #endif #if BYTE_ORDER >= 0 /* big-endian */ { /* * On big-endian machines, we must arrange the bytes in the * right order. */ const uint8_t *xp = data; int i; # if BYTE_ORDER == 0 X = xbuf; /* (dynamic only) */ # else # define xbuf X /* (static only) */ # endif for (i = 0; i < 16; ++i, xp += 4) xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); } #endif } #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) /* Round 1. */ /* Let [abcd k s i] denote the operation a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ #define F(x, y, z) (((x) & (y)) | (~(x) & (z))) #define SET(a, b, c, d, k, s, Ti)\ t = a + F(b,c,d) + X[k] + Ti;\ a = ROTATE_LEFT(t, s) + b /* Do the following 16 operations. */ SET(a, b, c, d, 0, 7, T1); SET(d, a, b, c, 1, 12, T2); SET(c, d, a, b, 2, 17, T3); SET(b, c, d, a, 3, 22, T4); SET(a, b, c, d, 4, 7, T5); SET(d, a, b, c, 5, 12, T6); SET(c, d, a, b, 6, 17, T7); SET(b, c, d, a, 7, 22, T8); SET(a, b, c, d, 8, 7, T9); SET(d, a, b, c, 9, 12, T10); SET(c, d, a, b, 10, 17, T11); SET(b, c, d, a, 11, 22, T12); SET(a, b, c, d, 12, 7, T13); SET(d, a, b, c, 13, 12, T14); SET(c, d, a, b, 14, 17, T15); SET(b, c, d, a, 15, 22, T16); #undef SET /* Round 2. */ /* Let [abcd k s i] denote the operation a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ #define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) #define SET(a, b, c, d, k, s, Ti)\ t = a + G(b,c,d) + X[k] + Ti;\ a = ROTATE_LEFT(t, s) + b /* Do the following 16 operations. */ SET(a, b, c, d, 1, 5, T17); SET(d, a, b, c, 6, 9, T18); SET(c, d, a, b, 11, 14, T19); SET(b, c, d, a, 0, 20, T20); SET(a, b, c, d, 5, 5, T21); SET(d, a, b, c, 10, 9, T22); SET(c, d, a, b, 15, 14, T23); SET(b, c, d, a, 4, 20, T24); SET(a, b, c, d, 9, 5, T25); SET(d, a, b, c, 14, 9, T26); SET(c, d, a, b, 3, 14, T27); SET(b, c, d, a, 8, 20, T28); SET(a, b, c, d, 13, 5, T29); SET(d, a, b, c, 2, 9, T30); SET(c, d, a, b, 7, 14, T31); SET(b, c, d, a, 12, 20, T32); #undef SET /* Round 3. */ /* Let [abcd k s t] denote the operation a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ #define H(x, y, z) ((x) ^ (y) ^ (z)) #define SET(a, b, c, d, k, s, Ti)\ t = a + H(b,c,d) + X[k] + Ti;\ a = ROTATE_LEFT(t, s) + b /* Do the following 16 operations. */ SET(a, b, c, d, 5, 4, T33); SET(d, a, b, c, 8, 11, T34); SET(c, d, a, b, 11, 16, T35); SET(b, c, d, a, 14, 23, T36); SET(a, b, c, d, 1, 4, T37); SET(d, a, b, c, 4, 11, T38); SET(c, d, a, b, 7, 16, T39); SET(b, c, d, a, 10, 23, T40); SET(a, b, c, d, 13, 4, T41); SET(d, a, b, c, 0, 11, T42); SET(c, d, a, b, 3, 16, T43); SET(b, c, d, a, 6, 23, T44); SET(a, b, c, d, 9, 4, T45); SET(d, a, b, c, 12, 11, T46); SET(c, d, a, b, 15, 16, T47); SET(b, c, d, a, 2, 23, T48); #undef SET /* Round 4. */ /* Let [abcd k s t] denote the operation a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ #define I(x, y, z) ((y) ^ ((x) | ~(z))) #define SET(a, b, c, d, k, s, Ti)\ t = a + I(b,c,d) + X[k] + Ti;\ a = ROTATE_LEFT(t, s) + b /* Do the following 16 operations. */ SET(a, b, c, d, 0, 6, T49); SET(d, a, b, c, 7, 10, T50); SET(c, d, a, b, 14, 15, T51); SET(b, c, d, a, 5, 21, T52); SET(a, b, c, d, 12, 6, T53); SET(d, a, b, c, 3, 10, T54); SET(c, d, a, b, 10, 15, T55); SET(b, c, d, a, 1, 21, T56); SET(a, b, c, d, 8, 6, T57); SET(d, a, b, c, 15, 10, T58); SET(c, d, a, b, 6, 15, T59); SET(b, c, d, a, 13, 21, T60); SET(a, b, c, d, 4, 6, T61); SET(d, a, b, c, 11, 10, T62); SET(c, d, a, b, 2, 15, T63); SET(b, c, d, a, 9, 21, T64); #undef SET /* Then perform the following additions. (That is increment each of the four registers by the value it had before this block was started.) */ md5->abcd[0] += a; md5->abcd[1] += b; md5->abcd[2] += c; md5->abcd[3] += d; } void bson_md5_init (bson_md5_t *pms) { pms->count[0] = pms->count[1] = 0; pms->abcd[0] = 0x67452301; pms->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476; pms->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301; pms->abcd[3] = 0x10325476; } void bson_md5_append (bson_md5_t *pms, const uint8_t *data, uint32_t nbytes) { const uint8_t *p = data; int left = nbytes; int offset = (pms->count[0] >> 3) & 63; uint32_t nbits = (uint32_t)(nbytes << 3); if (nbytes <= 0) return; /* Update the message length. */ pms->count[1] += nbytes >> 29; pms->count[0] += nbits; if (pms->count[0] < nbits) pms->count[1]++; /* Process an initial partial block. */ if (offset) { int copy = (offset + nbytes > 64 ? 64 - offset : nbytes); memcpy(pms->buf + offset, p, copy); if (offset + copy < 64) return; p += copy; left -= copy; bson_md5_process(pms, pms->buf); } /* Process full blocks. */ for (; left >= 64; p += 64, left -= 64) bson_md5_process(pms, p); /* Process a final partial block. */ if (left) memcpy(pms->buf, p, left); } void bson_md5_finish (bson_md5_t *pms, uint8_t digest[16]) { static const uint8_t pad[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; uint8_t data[8]; int i; /* Save the length before padding. */ for (i = 0; i < 8; ++i) data[i] = (uint8_t)(pms->count[i >> 2] >> ((i & 3) << 3)); /* Pad to 56 bytes mod 64. */ bson_md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); /* Append the length. */ bson_md5_append(pms, data, sizeof (data)); for (i = 0; i < 16; ++i) digest[i] = (uint8_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); } mongodb-1.1.5/src/libbson/src/bson/bson-md5.h0000664000175000017500000000553012673034026020555 0ustar jmikolajmikola/* Copyright (C) 1999, 2002 Aladdin Enterprises. All rights reserved. This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. L. Peter Deutsch ghost@aladdin.com */ /* $Id: md5.h,v 1.4 2002/04/13 19:20:28 lpd Exp $ */ /* Independent implementation of MD5 (RFC 1321). This code implements the MD5 Algorithm defined in RFC 1321, whose text is available at http://www.ietf.org/rfc/rfc1321.txt The code is derived from the text of the RFC, including the test suite (section A.5) but excluding the rest of Appendix A. It does not include any code or documentation that is identified in the RFC as being copyrighted. The original and principal author of md5.h is L. Peter Deutsch . Other authors are noted in the change history that follows (in reverse chronological order): 2002-04-13 lpd Removed support for non-ANSI compilers; removed references to Ghostscript; clarified derivation from RFC 1321; now handles byte order either statically or dynamically. 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5); added conditionalization for C++ compilation from Martin Purschke . 1999-05-03 lpd Original version. */ /* * The following MD5 implementation has been modified to use types as * specified in libbson. */ #ifndef BSON_MD5_H #define BSON_MD5_H #if !defined (BSON_INSIDE) && !defined (BSON_COMPILATION) # error "Only can be included directly." #endif #include "bson-endian.h" BSON_BEGIN_DECLS typedef struct { uint32_t count[2]; /* message length in bits, lsw first */ uint32_t abcd[4]; /* digest buffer */ uint8_t buf[64]; /* accumulate block */ } bson_md5_t; void bson_md5_init (bson_md5_t *pms); void bson_md5_append (bson_md5_t *pms, const uint8_t *data, uint32_t nbytes); void bson_md5_finish (bson_md5_t *pms, uint8_t digest[16]); BSON_END_DECLS #endif /* BSON_MD5_H */ mongodb-1.1.5/src/libbson/src/bson/bson-memory.c0000664000175000017500000001515012673034026021372 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include "bson-atomic.h" #include "bson-config.h" #include "bson-memory.h" static bson_mem_vtable_t gMemVtable = { malloc, calloc, #ifdef __APPLE__ reallocf, #else realloc, #endif free, }; /* *-------------------------------------------------------------------------- * * bson_malloc -- * * Allocates @num_bytes of memory and returns a pointer to it. If * malloc failed to allocate the memory, abort() is called. * * Libbson does not try to handle OOM conditions as it is beyond the * scope of this library to handle so appropriately. * * Parameters: * @num_bytes: The number of bytes to allocate. * * Returns: * A pointer if successful; otherwise abort() is called and this * function will never return. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void * bson_malloc (size_t num_bytes) /* IN */ { void *mem; if (!(mem = gMemVtable.malloc (num_bytes))) { abort (); } return mem; } /* *-------------------------------------------------------------------------- * * bson_malloc0 -- * * Like bson_malloc() except the memory is zeroed first. This is * similar to calloc() except that abort() is called in case of * failure to allocate memory. * * Parameters: * @num_bytes: The number of bytes to allocate. * * Returns: * A pointer if successful; otherwise abort() is called and this * function will never return. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void * bson_malloc0 (size_t num_bytes) /* IN */ { void *mem = NULL; if (BSON_LIKELY (num_bytes)) { if (BSON_UNLIKELY (!(mem = gMemVtable.calloc (1, num_bytes)))) { abort (); } } return mem; } /* *-------------------------------------------------------------------------- * * bson_realloc -- * * This function behaves similar to realloc() except that if there is * a failure abort() is called. * * Parameters: * @mem: The memory to realloc, or NULL. * @num_bytes: The size of the new allocation or 0 to free. * * Returns: * The new allocation if successful; otherwise abort() is called and * this function never returns. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void * bson_realloc (void *mem, /* IN */ size_t num_bytes) /* IN */ { /* * Not all platforms are guaranteed to free() the memory if a call to * realloc() with a size of zero occurs. Windows, Linux, and FreeBSD do, * however, OS X does not. */ if (BSON_UNLIKELY (num_bytes == 0)) { gMemVtable.free (mem); return NULL; } mem = gMemVtable.realloc (mem, num_bytes); if (BSON_UNLIKELY (!mem)) { abort (); } return mem; } /* *-------------------------------------------------------------------------- * * bson_realloc_ctx -- * * This wraps bson_realloc and provides a compatible api for similar * functions with a context * * Parameters: * @mem: The memory to realloc, or NULL. * @num_bytes: The size of the new allocation or 0 to free. * @ctx: Ignored * * Returns: * The new allocation if successful; otherwise abort() is called and * this function never returns. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void * bson_realloc_ctx (void *mem, /* IN */ size_t num_bytes, /* IN */ void *ctx) /* IN */ { return bson_realloc (mem, num_bytes); } /* *-------------------------------------------------------------------------- * * bson_free -- * * Frees @mem using the underlying allocator. * * Currently, this only calls free() directly, but that is subject to * change. * * Parameters: * @mem: An allocation to free. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void bson_free (void *mem) /* IN */ { gMemVtable.free (mem); } /* *-------------------------------------------------------------------------- * * bson_zero_free -- * * Frees @mem using the underlying allocator. @size bytes of @mem will * be zeroed before freeing the memory. This is useful in scenarios * where @mem contains passwords or other sensitive information. * * Parameters: * @mem: An allocation to free. * @size: The number of bytes in @mem. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void bson_zero_free (void *mem, /* IN */ size_t size) /* IN */ { if (BSON_LIKELY (mem)) { memset (mem, 0, size); gMemVtable.free (mem); } } /* *-------------------------------------------------------------------------- * * bson_mem_set_vtable -- * * This function will change our allocationt vtable. * * It is imperitive that this is called at the beginning of the * process before any memory has been allocated by the default * allocator. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void bson_mem_set_vtable (const bson_mem_vtable_t *vtable) { BSON_ASSERT (vtable); if (!vtable->malloc || !vtable->calloc || !vtable->realloc || !vtable->free) { fprintf (stderr, "Failure to install BSON vtable, " "missing functions.\n"); return; } gMemVtable = *vtable; } void bson_mem_restore_vtable (void) { bson_mem_vtable_t vtable = { malloc, calloc, #ifdef __APPLE__ reallocf, #else realloc, #endif free, }; bson_mem_set_vtable(&vtable); } mongodb-1.1.5/src/libbson/src/bson/bson-memory.h0000664000175000017500000000353412673034026021402 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef BSON_MEMORY_H #define BSON_MEMORY_H #if !defined (BSON_INSIDE) && !defined (BSON_COMPILATION) # error "Only can be included directly." #endif #include "bson-macros.h" #include "bson-types.h" BSON_BEGIN_DECLS typedef void *(*bson_realloc_func) (void *mem, size_t num_bytes, void *ctx); typedef struct _bson_mem_vtable_t { void *(*malloc) (size_t num_bytes); void *(*calloc) (size_t n_members, size_t num_bytes); void *(*realloc) (void *mem, size_t num_bytes); void (*free) (void *mem); void *padding [4]; } bson_mem_vtable_t; void bson_mem_set_vtable (const bson_mem_vtable_t *vtable); void bson_mem_restore_vtable (void); void *bson_malloc (size_t num_bytes); void *bson_malloc0 (size_t num_bytes); void *bson_realloc (void *mem, size_t num_bytes); void *bson_realloc_ctx (void *mem, size_t num_bytes, void *ctx); void bson_free (void *mem); void bson_zero_free (void *mem, size_t size); BSON_END_DECLS #endif /* BSON_MEMORY_H */ mongodb-1.1.5/src/libbson/src/bson/bson-oid.c0000664000175000017500000003431312673034026020637 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "bson-compat.h" #include #include #include #include #include "bson-context-private.h" #include "bson-md5.h" #include "bson-oid.h" #include "bson-string.h" /* * This table contains an array of two character pairs for every possible * uint8_t. It is used as a lookup table when encoding a bson_oid_t * to hex formatted ASCII. Performing two characters at a time roughly * reduces the number of operations by one-half. */ static const uint16_t gHexCharPairs[] = { #if BSON_BYTE_ORDER == BSON_BIG_ENDIAN 12336, 12337, 12338, 12339, 12340, 12341, 12342, 12343, 12344, 12345, 12385, 12386, 12387, 12388, 12389, 12390, 12592, 12593, 12594, 12595, 12596, 12597, 12598, 12599, 12600, 12601, 12641, 12642, 12643, 12644, 12645, 12646, 12848, 12849, 12850, 12851, 12852, 12853, 12854, 12855, 12856, 12857, 12897, 12898, 12899, 12900, 12901, 12902, 13104, 13105, 13106, 13107, 13108, 13109, 13110, 13111, 13112, 13113, 13153, 13154, 13155, 13156, 13157, 13158, 13360, 13361, 13362, 13363, 13364, 13365, 13366, 13367, 13368, 13369, 13409, 13410, 13411, 13412, 13413, 13414, 13616, 13617, 13618, 13619, 13620, 13621, 13622, 13623, 13624, 13625, 13665, 13666, 13667, 13668, 13669, 13670, 13872, 13873, 13874, 13875, 13876, 13877, 13878, 13879, 13880, 13881, 13921, 13922, 13923, 13924, 13925, 13926, 14128, 14129, 14130, 14131, 14132, 14133, 14134, 14135, 14136, 14137, 14177, 14178, 14179, 14180, 14181, 14182, 14384, 14385, 14386, 14387, 14388, 14389, 14390, 14391, 14392, 14393, 14433, 14434, 14435, 14436, 14437, 14438, 14640, 14641, 14642, 14643, 14644, 14645, 14646, 14647, 14648, 14649, 14689, 14690, 14691, 14692, 14693, 14694, 24880, 24881, 24882, 24883, 24884, 24885, 24886, 24887, 24888, 24889, 24929, 24930, 24931, 24932, 24933, 24934, 25136, 25137, 25138, 25139, 25140, 25141, 25142, 25143, 25144, 25145, 25185, 25186, 25187, 25188, 25189, 25190, 25392, 25393, 25394, 25395, 25396, 25397, 25398, 25399, 25400, 25401, 25441, 25442, 25443, 25444, 25445, 25446, 25648, 25649, 25650, 25651, 25652, 25653, 25654, 25655, 25656, 25657, 25697, 25698, 25699, 25700, 25701, 25702, 25904, 25905, 25906, 25907, 25908, 25909, 25910, 25911, 25912, 25913, 25953, 25954, 25955, 25956, 25957, 25958, 26160, 26161, 26162, 26163, 26164, 26165, 26166, 26167, 26168, 26169, 26209, 26210, 26211, 26212, 26213, 26214 #else 12336, 12592, 12848, 13104, 13360, 13616, 13872, 14128, 14384, 14640, 24880, 25136, 25392, 25648, 25904, 26160, 12337, 12593, 12849, 13105, 13361, 13617, 13873, 14129, 14385, 14641, 24881, 25137, 25393, 25649, 25905, 26161, 12338, 12594, 12850, 13106, 13362, 13618, 13874, 14130, 14386, 14642, 24882, 25138, 25394, 25650, 25906, 26162, 12339, 12595, 12851, 13107, 13363, 13619, 13875, 14131, 14387, 14643, 24883, 25139, 25395, 25651, 25907, 26163, 12340, 12596, 12852, 13108, 13364, 13620, 13876, 14132, 14388, 14644, 24884, 25140, 25396, 25652, 25908, 26164, 12341, 12597, 12853, 13109, 13365, 13621, 13877, 14133, 14389, 14645, 24885, 25141, 25397, 25653, 25909, 26165, 12342, 12598, 12854, 13110, 13366, 13622, 13878, 14134, 14390, 14646, 24886, 25142, 25398, 25654, 25910, 26166, 12343, 12599, 12855, 13111, 13367, 13623, 13879, 14135, 14391, 14647, 24887, 25143, 25399, 25655, 25911, 26167, 12344, 12600, 12856, 13112, 13368, 13624, 13880, 14136, 14392, 14648, 24888, 25144, 25400, 25656, 25912, 26168, 12345, 12601, 12857, 13113, 13369, 13625, 13881, 14137, 14393, 14649, 24889, 25145, 25401, 25657, 25913, 26169, 12385, 12641, 12897, 13153, 13409, 13665, 13921, 14177, 14433, 14689, 24929, 25185, 25441, 25697, 25953, 26209, 12386, 12642, 12898, 13154, 13410, 13666, 13922, 14178, 14434, 14690, 24930, 25186, 25442, 25698, 25954, 26210, 12387, 12643, 12899, 13155, 13411, 13667, 13923, 14179, 14435, 14691, 24931, 25187, 25443, 25699, 25955, 26211, 12388, 12644, 12900, 13156, 13412, 13668, 13924, 14180, 14436, 14692, 24932, 25188, 25444, 25700, 25956, 26212, 12389, 12645, 12901, 13157, 13413, 13669, 13925, 14181, 14437, 14693, 24933, 25189, 25445, 25701, 25957, 26213, 12390, 12646, 12902, 13158, 13414, 13670, 13926, 14182, 14438, 14694, 24934, 25190, 25446, 25702, 25958, 26214 #endif }; /* *-------------------------------------------------------------------------- * * bson_oid_init_sequence -- * * Initializes @oid with the next oid in the sequence. The first 4 * bytes contain the current time and the following 8 contain a 64-bit * integer in big-endian format. * * The bson_oid_t generated by this function is not guaranteed to be * globally unique. Only unique within this context. It is however, * guaranteed to be sequential. * * Returns: * None. * * Side effects: * @oid is initialized. * *-------------------------------------------------------------------------- */ void bson_oid_init_sequence (bson_oid_t *oid, /* OUT */ bson_context_t *context) /* IN */ { uint32_t now = (uint32_t)(time (NULL)); if (!context) { context = bson_context_get_default (); } now = BSON_UINT32_TO_BE (now); memcpy (&oid->bytes[0], &now, sizeof (now)); context->oid_get_seq64 (context, oid); } /* *-------------------------------------------------------------------------- * * bson_oid_init -- * * Generates bytes for a new bson_oid_t and stores them in @oid. The * bytes will be generated according to the specification and includes * the current time, first 3 bytes of MD5(hostname), pid (or tid), and * monotonic counter. * * The bson_oid_t generated by this function is not guaranteed to be * globally unique. Only unique within this context. It is however, * guaranteed to be sequential. * * Returns: * None. * * Side effects: * @oid is initialized. * *-------------------------------------------------------------------------- */ void bson_oid_init (bson_oid_t *oid, /* OUT */ bson_context_t *context) /* IN */ { uint32_t now = (uint32_t)(time (NULL)); BSON_ASSERT (oid); if (!context) { context = bson_context_get_default (); } now = BSON_UINT32_TO_BE (now); memcpy (&oid->bytes[0], &now, sizeof (now)); context->oid_get_host (context, oid); context->oid_get_pid (context, oid); context->oid_get_seq32 (context, oid); } /** * bson_oid_init_from_data: * @oid: A bson_oid_t to initialize. * @bytes: A 12-byte buffer to copy into @oid. * */ /* *-------------------------------------------------------------------------- * * bson_oid_init_from_data -- * * Initializes an @oid from @data. @data MUST be a buffer of at least * 12 bytes. This method is analagous to memcpy()'ing data into @oid. * * Returns: * None. * * Side effects: * @oid is initialized. * *-------------------------------------------------------------------------- */ void bson_oid_init_from_data (bson_oid_t *oid, /* OUT */ const uint8_t *data) /* IN */ { BSON_ASSERT (oid); BSON_ASSERT (data); memcpy (oid, data, 12); } /* *-------------------------------------------------------------------------- * * bson_oid_init_from_string -- * * Parses @str containing hex formatted bytes of an object id and * places the bytes in @oid. * * Parameters: * @oid: A bson_oid_t * @str: A string containing at least 24 characters. * * Returns: * None. * * Side effects: * @oid is initialized. * *-------------------------------------------------------------------------- */ void bson_oid_init_from_string (bson_oid_t *oid, /* OUT */ const char *str) /* IN */ { BSON_ASSERT (oid); BSON_ASSERT (str); bson_oid_init_from_string_unsafe (oid, str); } /* *-------------------------------------------------------------------------- * * bson_oid_get_time_t -- * * Fetches the time for which @oid was created. * * Returns: * A time_t. * * Side effects: * None. * *-------------------------------------------------------------------------- */ time_t bson_oid_get_time_t (const bson_oid_t *oid) /* IN */ { BSON_ASSERT (oid); return bson_oid_get_time_t_unsafe (oid); } /* *-------------------------------------------------------------------------- * * bson_oid_to_string -- * * Formats a bson_oid_t into a string. @str must contain enough bytes * for the resulting string which is 25 bytes with a terminating * NUL-byte. * * Parameters: * @oid: A bson_oid_t. * @str: A location to store the resulting string. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void bson_oid_to_string (const bson_oid_t *oid, /* IN */ char str[BSON_ENSURE_ARRAY_PARAM_SIZE(25)]) /* OUT */ { #if !defined(__i386__) && !defined(__x86_64__) BSON_ASSERT (oid); BSON_ASSERT (str); bson_snprintf (str, 25, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", oid->bytes[0], oid->bytes[1], oid->bytes[2], oid->bytes[3], oid->bytes[4], oid->bytes[5], oid->bytes[6], oid->bytes[7], oid->bytes[8], oid->bytes[9], oid->bytes[10], oid->bytes[11]); #else uint16_t *dst; uint8_t *id = (uint8_t *)oid; BSON_ASSERT (oid); BSON_ASSERT (str); dst = (uint16_t *)(void *)str; dst[0] = gHexCharPairs[id[0]]; dst[1] = gHexCharPairs[id[1]]; dst[2] = gHexCharPairs[id[2]]; dst[3] = gHexCharPairs[id[3]]; dst[4] = gHexCharPairs[id[4]]; dst[5] = gHexCharPairs[id[5]]; dst[6] = gHexCharPairs[id[6]]; dst[7] = gHexCharPairs[id[7]]; dst[8] = gHexCharPairs[id[8]]; dst[9] = gHexCharPairs[id[9]]; dst[10] = gHexCharPairs[id[10]]; dst[11] = gHexCharPairs[id[11]]; str[24] = '\0'; #endif } /* *-------------------------------------------------------------------------- * * bson_oid_hash -- * * Hashes the bytes of the provided bson_oid_t using DJB hash. This * allows bson_oid_t to be used as keys in a hash table. * * Returns: * A hash value corresponding to @oid. * * Side effects: * None. * *-------------------------------------------------------------------------- */ uint32_t bson_oid_hash (const bson_oid_t *oid) /* IN */ { BSON_ASSERT (oid); return bson_oid_hash_unsafe (oid); } /* *-------------------------------------------------------------------------- * * bson_oid_compare -- * * A qsort() style compare function that will return less than zero if * @oid1 is less than @oid2, zero if they are the same, and greater * than zero if @oid2 is greater than @oid1. * * Returns: * A qsort() style compare integer. * * Side effects: * None. * *-------------------------------------------------------------------------- */ int bson_oid_compare (const bson_oid_t *oid1, /* IN */ const bson_oid_t *oid2) /* IN */ { BSON_ASSERT (oid1); BSON_ASSERT (oid2); return bson_oid_compare_unsafe (oid1, oid2); } /* *-------------------------------------------------------------------------- * * bson_oid_equal -- * * Compares for equality of @oid1 and @oid2. If they are equal, then * true is returned, otherwise false. * * Returns: * A boolean indicating the equality of @oid1 and @oid2. * * Side effects: * None. * *-------------------------------------------------------------------------- */ bool bson_oid_equal (const bson_oid_t *oid1, /* IN */ const bson_oid_t *oid2) /* IN */ { BSON_ASSERT (oid1); BSON_ASSERT (oid2); return bson_oid_equal_unsafe (oid1, oid2); } /* *-------------------------------------------------------------------------- * * bson_oid_copy -- * * Copies the contents of @src to @dst. * * Parameters: * @src: A bson_oid_t to copy from. * @dst: A bson_oid_t to copy to. * * Returns: * None. * * Side effects: * @dst will contain a copy of the data in @src. * *-------------------------------------------------------------------------- */ void bson_oid_copy (const bson_oid_t *src, /* IN */ bson_oid_t *dst) /* OUT */ { BSON_ASSERT (src); BSON_ASSERT (dst); bson_oid_copy_unsafe (src, dst); } /* *-------------------------------------------------------------------------- * * bson_oid_is_valid -- * * Validates that @str is a valid OID string. @length MUST be 24, but * is provided as a parameter to simplify calling code. * * Parameters: * @str: A string to validate. * @length: The length of @str. * * Returns: * true if @str can be passed to bson_oid_init_from_string(). * * Side effects: * None. * *-------------------------------------------------------------------------- */ bool bson_oid_is_valid (const char *str, /* IN */ size_t length) /* IN */ { size_t i; BSON_ASSERT (str); if ((length == 25) && (str [24] == '\0')) { length = 24; } if (length == 24) { for (i = 0; i < length; i++) { switch (str[i]) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': break; default: return false; } } return true; } return false; } mongodb-1.1.5/src/libbson/src/bson/bson-oid.h0000664000175000017500000001467012673034026020650 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef BSON_OID_H #define BSON_OID_H #if !defined (BSON_INSIDE) && !defined (BSON_COMPILATION) # error "Only can be included directly." #endif #include #include "bson-context.h" #include "bson-macros.h" #include "bson-types.h" #include "bson-endian.h" BSON_BEGIN_DECLS int bson_oid_compare (const bson_oid_t *oid1, const bson_oid_t *oid2); void bson_oid_copy (const bson_oid_t *src, bson_oid_t *dst); bool bson_oid_equal (const bson_oid_t *oid1, const bson_oid_t *oid2); bool bson_oid_is_valid (const char *str, size_t length); time_t bson_oid_get_time_t (const bson_oid_t *oid); uint32_t bson_oid_hash (const bson_oid_t *oid); void bson_oid_init (bson_oid_t *oid, bson_context_t *context); void bson_oid_init_from_data (bson_oid_t *oid, const uint8_t *data); void bson_oid_init_from_string (bson_oid_t *oid, const char *str); void bson_oid_init_sequence (bson_oid_t *oid, bson_context_t *context); void bson_oid_to_string (const bson_oid_t *oid, char str[25]); /** * bson_oid_compare_unsafe: * @oid1: A bson_oid_t. * @oid2: A bson_oid_t. * * Performs a qsort() style comparison between @oid1 and @oid2. * * This function is meant to be as fast as possible and therefore performs * no argument validation. That is the callers responsibility. * * Returns: An integer < 0 if @oid1 is less than @oid2. Zero if they are equal. * An integer > 0 if @oid1 is greater than @oid2. */ static BSON_INLINE int bson_oid_compare_unsafe (const bson_oid_t *oid1, const bson_oid_t *oid2) { return memcmp (oid1, oid2, sizeof *oid1); } /** * bson_oid_equal_unsafe: * @oid1: A bson_oid_t. * @oid2: A bson_oid_t. * * Checks the equality of @oid1 and @oid2. * * This function is meant to be as fast as possible and therefore performs * no checks for argument validity. That is the callers responsibility. * * Returns: true if @oid1 and @oid2 are equal; otherwise false. */ static BSON_INLINE bool bson_oid_equal_unsafe (const bson_oid_t *oid1, const bson_oid_t *oid2) { return !memcmp (oid1, oid2, sizeof *oid1); } /** * bson_oid_hash_unsafe: * @oid: A bson_oid_t. * * This function performs a DJB style hash upon the bytes contained in @oid. * The result is a hash key suitable for use in a hashtable. * * This function is meant to be as fast as possible and therefore performs no * validation of arguments. The caller is responsible to ensure they are * passing valid arguments. * * Returns: A uint32_t containing a hash code. */ static BSON_INLINE uint32_t bson_oid_hash_unsafe (const bson_oid_t *oid) { uint32_t hash = 5381; uint32_t i; for (i = 0; i < sizeof oid->bytes; i++) { hash = ((hash << 5) + hash) + oid->bytes[i]; } return hash; } /** * bson_oid_copy_unsafe: * @src: A bson_oid_t to copy from. * @dst: A bson_oid_t to copy into. * * Copies the contents of @src into @dst. This function is meant to be as * fast as possible and therefore performs no argument checking. It is the * callers responsibility to ensure they are passing valid data into the * function. */ static BSON_INLINE void bson_oid_copy_unsafe (const bson_oid_t *src, bson_oid_t *dst) { memcpy (dst, src, sizeof *src); } /** * bson_oid_parse_hex_char: * @hex: A character to parse to its integer value. * * This function contains a jump table to return the integer value for a * character containing a hexidecimal value (0-9, a-f, A-F). If the character * is not a hexidecimal character then zero is returned. * * Returns: An integer between 0 and 15. */ static BSON_INLINE uint8_t bson_oid_parse_hex_char (char hex) { switch (hex) { case '0': return 0; case '1': return 1; case '2': return 2; case '3': return 3; case '4': return 4; case '5': return 5; case '6': return 6; case '7': return 7; case '8': return 8; case '9': return 9; case 'a': case 'A': return 0xa; case 'b': case 'B': return 0xb; case 'c': case 'C': return 0xc; case 'd': case 'D': return 0xd; case 'e': case 'E': return 0xe; case 'f': case 'F': return 0xf; default: return 0; } } /** * bson_oid_init_from_string_unsafe: * @oid: A bson_oid_t to store the result. * @str: A 24-character hexidecimal encoded string. * * Parses a string containing 24 hexidecimal encoded bytes into a bson_oid_t. * This function is meant to be as fast as possible and inlined into your * code. For that purpose, the function does not perform any sort of bounds * checking and it is the callers responsibility to ensure they are passing * valid input to the function. */ static BSON_INLINE void bson_oid_init_from_string_unsafe (bson_oid_t *oid, const char *str) { int i; for (i = 0; i < 12; i++) { oid->bytes[i] = ((bson_oid_parse_hex_char (str[2 * i]) << 4) | (bson_oid_parse_hex_char (str[2 * i + 1]))); } } /** * bson_oid_get_time_t_unsafe: * @oid: A bson_oid_t. * * Fetches the time @oid was generated. * * Returns: A time_t containing the UNIX timestamp of generation. */ static BSON_INLINE time_t bson_oid_get_time_t_unsafe (const bson_oid_t *oid) { uint32_t t; memcpy (&t, oid, sizeof (t)); return BSON_UINT32_FROM_BE (t); } BSON_END_DECLS #endif /* BSON_OID_H */ mongodb-1.1.5/src/libbson/src/bson/bson-private.h0000664000175000017500000000433112673034026021540 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef BSON_PRIVATE_H #define BSON_PRIVATE_H #include "bson-macros.h" #include "bson-memory.h" #include "bson-types.h" BSON_BEGIN_DECLS typedef enum { BSON_FLAG_NONE = 0, BSON_FLAG_INLINE = (1 << 0), BSON_FLAG_STATIC = (1 << 1), BSON_FLAG_RDONLY = (1 << 2), BSON_FLAG_CHILD = (1 << 3), BSON_FLAG_IN_CHILD = (1 << 4), BSON_FLAG_NO_FREE = (1 << 5), } bson_flags_t; BSON_ALIGNED_BEGIN (128) typedef struct { bson_flags_t flags; uint32_t len; uint8_t data [120]; } bson_impl_inline_t BSON_ALIGNED_END (128); BSON_STATIC_ASSERT (sizeof (bson_impl_inline_t) == 128); BSON_ALIGNED_BEGIN (128) typedef struct { bson_flags_t flags; /* flags describing the bson_t */ uint32_t len; /* length of bson document in bytes */ bson_t *parent; /* parent bson if a child */ uint32_t depth; /* Subdocument depth. */ uint8_t **buf; /* pointer to buffer pointer */ size_t *buflen; /* pointer to buffer length */ size_t offset; /* our offset inside *buf */ uint8_t *alloc; /* buffer that we own. */ size_t alloclen; /* length of buffer that we own. */ bson_realloc_func realloc; /* our realloc implementation */ void *realloc_func_ctx; /* context for our realloc func */ } bson_impl_alloc_t BSON_ALIGNED_END (128); BSON_STATIC_ASSERT (sizeof (bson_impl_alloc_t) <= 128); BSON_END_DECLS #endif /* BSON_PRIVATE_H */ mongodb-1.1.5/src/libbson/src/bson/bson-reader.c0000664000175000017500000004553412673034026021335 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "bson.h" #include #include #ifdef BSON_OS_WIN32 # include # include #endif #include #include #include #include #include "bson-reader.h" #include "bson-memory.h" typedef enum { BSON_READER_HANDLE = 1, BSON_READER_DATA = 2, } bson_reader_type_t; typedef struct { bson_reader_type_t type; void *handle; bool done : 1; bool failed : 1; size_t end; size_t len; size_t offset; size_t bytes_read; bson_t inline_bson; uint8_t *data; bson_reader_read_func_t read_func; bson_reader_destroy_func_t destroy_func; } bson_reader_handle_t; typedef struct { int fd; bool do_close; } bson_reader_handle_fd_t; typedef struct { bson_reader_type_t type; const uint8_t *data; size_t length; size_t offset; bson_t inline_bson; } bson_reader_data_t; /* *-------------------------------------------------------------------------- * * _bson_reader_handle_fill_buffer -- * * Attempt to read as much as possible until the underlying buffer * in @reader is filled or we have reached end-of-stream or * read failure. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static void _bson_reader_handle_fill_buffer (bson_reader_handle_t *reader) /* IN */ { ssize_t ret; /* * Handle first read specially. */ if ((!reader->done) && (!reader->offset) && (!reader->end)) { ret = reader->read_func (reader->handle, &reader->data[0], reader->len); if (ret <= 0) { reader->done = true; return; } reader->bytes_read += ret; reader->end = ret; return; } /* * Move valid data to head. */ memmove (&reader->data[0], &reader->data[reader->offset], reader->end - reader->offset); reader->end = reader->end - reader->offset; reader->offset = 0; /* * Read in data to fill the buffer. */ ret = reader->read_func (reader->handle, &reader->data[reader->end], reader->len - reader->end); if (ret <= 0) { reader->done = true; reader->failed = (ret < 0); } else { reader->bytes_read += ret; reader->end += ret; } BSON_ASSERT (reader->offset == 0); BSON_ASSERT (reader->end <= reader->len); } /* *-------------------------------------------------------------------------- * * bson_reader_new_from_handle -- * * Allocates and initializes a new bson_reader_t using the opaque * handle provided. * * Parameters: * @handle: an opaque handle to use to read data. * @rf: a function to perform reads on @handle. * @df: a function to release @handle, or NULL. * * Returns: * A newly allocated bson_reader_t if successful, otherwise NULL. * Free the successful result with bson_reader_destroy(). * * Side effects: * None. * *-------------------------------------------------------------------------- */ bson_reader_t * bson_reader_new_from_handle (void *handle, bson_reader_read_func_t rf, bson_reader_destroy_func_t df) { bson_reader_handle_t *real; BSON_ASSERT (handle); BSON_ASSERT (rf); real = bson_malloc0 (sizeof *real); real->type = BSON_READER_HANDLE; real->data = bson_malloc0 (1024); real->handle = handle; real->len = 1024; real->offset = 0; bson_reader_set_read_func ((bson_reader_t *)real, rf); if (df) { bson_reader_set_destroy_func ((bson_reader_t *)real, df); } _bson_reader_handle_fill_buffer (real); return (bson_reader_t *)real; } /* *-------------------------------------------------------------------------- * * _bson_reader_handle_fd_destroy -- * * Cleanup allocations associated with state created in * bson_reader_new_from_fd(). * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static void _bson_reader_handle_fd_destroy (void *handle) /* IN */ { bson_reader_handle_fd_t *fd = handle; if (fd) { if ((fd->fd != -1) && fd->do_close) { #ifdef _WIN32 _close (fd->fd); #else close (fd->fd); #endif } bson_free (fd); } } /* *-------------------------------------------------------------------------- * * _bson_reader_handle_fd_read -- * * Perform read on opaque handle created in * bson_reader_new_from_fd(). * * The underlying file descriptor is read from the current position * using the bson_reader_handle_fd_t allocated. * * Returns: * -1 on failure. * 0 on end of stream. * Greater than zero on success. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static ssize_t _bson_reader_handle_fd_read (void *handle, /* IN */ void *buf, /* IN */ size_t len) /* IN */ { bson_reader_handle_fd_t *fd = handle; ssize_t ret = -1; if (fd && (fd->fd != -1)) { again: #ifdef BSON_OS_WIN32 ret = _read (fd->fd, buf, (unsigned int)len); #else ret = read (fd->fd, buf, len); #endif if ((ret == -1) && (errno == EAGAIN)) { goto again; } } return ret; } /* *-------------------------------------------------------------------------- * * bson_reader_new_from_fd -- * * Create a new bson_reader_t using the file-descriptor provided. * * Parameters: * @fd: a libc style file-descriptor. * @close_on_destroy: if close() should be called on @fd when * bson_reader_destroy() is called. * * Returns: * A newly allocated bson_reader_t on success; otherwise NULL. * * Side effects: * None. * *-------------------------------------------------------------------------- */ bson_reader_t * bson_reader_new_from_fd (int fd, /* IN */ bool close_on_destroy) /* IN */ { bson_reader_handle_fd_t *handle; BSON_ASSERT (fd != -1); handle = bson_malloc0 (sizeof *handle); handle->fd = fd; handle->do_close = close_on_destroy; return bson_reader_new_from_handle (handle, _bson_reader_handle_fd_read, _bson_reader_handle_fd_destroy); } /** * bson_reader_set_read_func: * @reader: A bson_reader_t. * * Note that @reader must be initialized by bson_reader_init_from_handle(), or data * will be destroyed. */ /* *-------------------------------------------------------------------------- * * bson_reader_set_read_func -- * * Set the read func to be provided for @reader. * * You probably want to use bson_reader_new_from_handle() or * bson_reader_new_from_fd() instead. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void bson_reader_set_read_func (bson_reader_t *reader, /* IN */ bson_reader_read_func_t func) /* IN */ { bson_reader_handle_t *real = (bson_reader_handle_t *)reader; BSON_ASSERT (reader->type == BSON_READER_HANDLE); real->read_func = func; } /* *-------------------------------------------------------------------------- * * bson_reader_set_destroy_func -- * * Set the function to cleanup state when @reader is destroyed. * * You probably want bson_reader_new_from_fd() or * bson_reader_new_from_handle() instead. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void bson_reader_set_destroy_func (bson_reader_t *reader, /* IN */ bson_reader_destroy_func_t func) /* IN */ { bson_reader_handle_t *real = (bson_reader_handle_t *)reader; BSON_ASSERT (reader->type == BSON_READER_HANDLE); real->destroy_func = func; } /* *-------------------------------------------------------------------------- * * _bson_reader_handle_grow_buffer -- * * Grow the buffer to the next power of two. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static void _bson_reader_handle_grow_buffer (bson_reader_handle_t *reader) /* IN */ { size_t size; size = reader->len * 2; reader->data = bson_realloc (reader->data, size); reader->len = size; } /* *-------------------------------------------------------------------------- * * _bson_reader_handle_tell -- * * Tell the current position within the underlying file-descriptor. * * Returns: * An off_t containing the current offset. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static off_t _bson_reader_handle_tell (bson_reader_handle_t *reader) /* IN */ { off_t off; off = (off_t)reader->bytes_read; off -= (off_t)reader->end; off += (off_t)reader->offset; return off; } /* *-------------------------------------------------------------------------- * * _bson_reader_handle_read -- * * Read the next chunk of data from the underlying file descriptor * and return a bson_t which should not be modified. * * There was a failure if NULL is returned and @reached_eof is * not set to true. * * Returns: * NULL on failure or end of stream. * * Side effects: * @reached_eof is set if non-NULL. * *-------------------------------------------------------------------------- */ static const bson_t * _bson_reader_handle_read (bson_reader_handle_t *reader, /* IN */ bool *reached_eof) /* IN */ { int32_t blen; if (reached_eof) { *reached_eof = false; } while (!reader->done) { if ((reader->end - reader->offset) < 4) { _bson_reader_handle_fill_buffer (reader); continue; } memcpy (&blen, &reader->data[reader->offset], sizeof blen); blen = BSON_UINT32_FROM_LE (blen); if (blen < 5) { return NULL; } if (blen > (int32_t)(reader->end - reader->offset)) { if (blen > (int32_t)reader->len) { _bson_reader_handle_grow_buffer (reader); } _bson_reader_handle_fill_buffer (reader); continue; } if (!bson_init_static (&reader->inline_bson, &reader->data[reader->offset], (uint32_t)blen)) { return NULL; } reader->offset += blen; return &reader->inline_bson; } if (reached_eof) { *reached_eof = reader->done && !reader->failed; } return NULL; } /* *-------------------------------------------------------------------------- * * bson_reader_new_from_data -- * * Allocates and initializes a new bson_reader_t that will the memory * provided as a stream of BSON documents. * * Parameters: * @data: A buffer to read BSON documents from. * @length: The length of @data. * * Returns: * A newly allocated bson_reader_t that should be freed with * bson_reader_destroy(). * * Side effects: * None. * *-------------------------------------------------------------------------- */ bson_reader_t * bson_reader_new_from_data (const uint8_t *data, /* IN */ size_t length) /* IN */ { bson_reader_data_t *real; BSON_ASSERT (data); real = (bson_reader_data_t*)bson_malloc0 (sizeof *real); real->type = BSON_READER_DATA; real->data = data; real->length = length; real->offset = 0; return (bson_reader_t *)real; } /* *-------------------------------------------------------------------------- * * _bson_reader_data_read -- * * Read the next document from the underlying buffer. * * Returns: * NULL on failure or end of stream. * a bson_t which should not be modified. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static const bson_t * _bson_reader_data_read (bson_reader_data_t *reader, /* IN */ bool *reached_eof) /* IN */ { int32_t blen; if (reached_eof) { *reached_eof = false; } if ((reader->offset + 4) < reader->length) { memcpy (&blen, &reader->data[reader->offset], sizeof blen); blen = BSON_UINT32_FROM_LE (blen); if (blen < 5) { return NULL; } if (blen > (int32_t)(reader->length - reader->offset)) { return NULL; } if (!bson_init_static (&reader->inline_bson, &reader->data[reader->offset], (uint32_t)blen)) { return NULL; } reader->offset += blen; return &reader->inline_bson; } if (reached_eof) { *reached_eof = (reader->offset == reader->length); } return NULL; } /* *-------------------------------------------------------------------------- * * _bson_reader_data_tell -- * * Tell the current position in the underlying buffer. * * Returns: * An off_t of the current offset. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static off_t _bson_reader_data_tell (bson_reader_data_t *reader) /* IN */ { return (off_t)reader->offset; } /* *-------------------------------------------------------------------------- * * bson_reader_destroy -- * * Release a bson_reader_t created with bson_reader_new_from_data(), * bson_reader_new_from_fd(), or bson_reader_new_from_handle(). * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void bson_reader_destroy (bson_reader_t *reader) /* IN */ { BSON_ASSERT (reader); switch (reader->type) { case 0: break; case BSON_READER_HANDLE: { bson_reader_handle_t *handle = (bson_reader_handle_t *)reader; if (handle->destroy_func) { handle->destroy_func(handle->handle); } bson_free (handle->data); } break; case BSON_READER_DATA: break; default: fprintf (stderr, "No such reader type: %02x\n", reader->type); break; } reader->type = 0; bson_free (reader); } /* *-------------------------------------------------------------------------- * * bson_reader_read -- * * Reads the next bson_t in the underlying memory or storage. The * resulting bson_t should not be modified or freed. You may copy it * and iterate over it. Functions that take a const bson_t* are safe * to use. * * This structure does not survive calls to bson_reader_read() or * bson_reader_destroy() as it uses memory allocated by the reader or * underlying storage/memory. * * If NULL is returned then @reached_eof will be set to true if the * end of the file or buffer was reached. This indicates if there was * an error parsing the document stream. * * Returns: * A const bson_t that should not be modified or freed. * NULL on failure or end of stream. * * Side effects: * @reached_eof is set if non-NULL. * *-------------------------------------------------------------------------- */ const bson_t * bson_reader_read (bson_reader_t *reader, /* IN */ bool *reached_eof) /* OUT */ { BSON_ASSERT (reader); switch (reader->type) { case BSON_READER_HANDLE: return _bson_reader_handle_read ((bson_reader_handle_t *)reader, reached_eof); case BSON_READER_DATA: return _bson_reader_data_read ((bson_reader_data_t *)reader, reached_eof); default: fprintf (stderr, "No such reader type: %02x\n", reader->type); break; } return NULL; } /* *-------------------------------------------------------------------------- * * bson_reader_tell -- * * Return the current position in the underlying reader. This will * always be at the beginning of a bson document or end of file. * * Returns: * An off_t containing the current offset. * * Side effects: * None. * *-------------------------------------------------------------------------- */ off_t bson_reader_tell (bson_reader_t *reader) /* IN */ { BSON_ASSERT (reader); switch (reader->type) { case BSON_READER_HANDLE: return _bson_reader_handle_tell ((bson_reader_handle_t *)reader); case BSON_READER_DATA: return _bson_reader_data_tell ((bson_reader_data_t *)reader); default: fprintf (stderr, "No such reader type: %02x\n", reader->type); return -1; } } /* *-------------------------------------------------------------------------- * * bson_reader_new_from_file -- * * A convenience function to open a file containing sequential * bson documents and read them using bson_reader_t. * * Returns: * A new bson_reader_t if successful, otherwise NULL and * @error is set. Free the non-NULL result with * bson_reader_destroy(). * * Side effects: * @error may be set. * *-------------------------------------------------------------------------- */ bson_reader_t * bson_reader_new_from_file (const char *path, /* IN */ bson_error_t *error) /* OUT */ { char errmsg_buf[BSON_ERROR_BUFFER_SIZE]; char *errmsg; int fd; BSON_ASSERT (path); #ifdef BSON_OS_WIN32 if (_sopen_s (&fd, path, (_O_RDONLY | _O_BINARY), _SH_DENYNO, 0) != 0) { fd = -1; } #else fd = open (path, O_RDONLY); #endif if (fd == -1) { errmsg = bson_strerror_r (errno, errmsg_buf, sizeof errmsg_buf); bson_set_error (error, BSON_ERROR_READER, BSON_ERROR_READER_BADFD, "%s", errmsg); return NULL; } return bson_reader_new_from_fd (fd, true); } mongodb-1.1.5/src/libbson/src/bson/bson-reader.h0000664000175000017500000000737012673034026021336 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef BSON_READER_H #define BSON_READER_H #if !defined (BSON_INSIDE) && !defined (BSON_COMPILATION) # error "Only can be included directly." #endif #include "bson-compat.h" #include "bson-oid.h" #include "bson-types.h" BSON_BEGIN_DECLS #define BSON_ERROR_READER_BADFD 1 /* *-------------------------------------------------------------------------- * * bson_reader_read_func_t -- * * This function is a callback used by bson_reader_t to read the * next chunk of data from the underlying opaque file descriptor. * * This function is meant to operate similar to the read() function * as part of libc on UNIX-like systems. * * Parameters: * @handle: The handle to read from. * @buf: The buffer to read into. * @count: The number of bytes to read. * * Returns: * 0 for end of stream. * -1 for read failure. * Greater than zero for number of bytes read into @buf. * * Side effects: * None. * *-------------------------------------------------------------------------- */ typedef ssize_t (*bson_reader_read_func_t) (void *handle, /* IN */ void *buf, /* IN */ size_t count); /* IN */ /* *-------------------------------------------------------------------------- * * bson_reader_destroy_func_t -- * * Destroy callback to release any resources associated with the * opaque handle. * * Parameters: * @handle: the handle provided to bson_reader_new_from_handle(). * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ typedef void (*bson_reader_destroy_func_t) (void *handle); /* IN */ bson_reader_t *bson_reader_new_from_handle (void *handle, bson_reader_read_func_t rf, bson_reader_destroy_func_t df); bson_reader_t *bson_reader_new_from_fd (int fd, bool close_on_destroy); bson_reader_t *bson_reader_new_from_file (const char *path, bson_error_t *error); bson_reader_t *bson_reader_new_from_data (const uint8_t *data, size_t length); void bson_reader_destroy (bson_reader_t *reader); void bson_reader_set_read_func (bson_reader_t *reader, bson_reader_read_func_t func); void bson_reader_set_destroy_func (bson_reader_t *reader, bson_reader_destroy_func_t func); const bson_t *bson_reader_read (bson_reader_t *reader, bool *reached_eof); off_t bson_reader_tell (bson_reader_t *reader); BSON_END_DECLS #endif /* BSON_READER_H */ mongodb-1.1.5/src/libbson/src/bson/bson-stdint-win32.h0000664000175000017500000001763412673034026022345 0ustar jmikolajmikola// ISO C9x compliant stdint.h for Microsoft Visual Studio // Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 // // Copyright (c) 2006-2013 Alexander Chemeris // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // 1. Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // // 3. Neither the name of the product nor the names of its contributors may // be used to endorse or promote products derived from this software // without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO // EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // /////////////////////////////////////////////////////////////////////////////// #ifndef _MSC_VER // [ #error "Use this header only with Microsoft Visual C++ compilers!" #endif // _MSC_VER ] #ifndef _MSC_STDINT_H_ // [ #define _MSC_STDINT_H_ #if _MSC_VER > 1000 #pragma once #endif #if _MSC_VER >= 1600 // [ #include #else // ] _MSC_VER >= 1600 [ #include // For Visual Studio 6 in C++ mode and for many Visual Studio versions when // compiling for ARM we should wrap include with 'extern "C++" {}' // or compiler give many errors like this: // error C2733: second C linkage of overloaded function 'wmemchr' not allowed #ifdef __cplusplus extern "C" { #endif # include #ifdef __cplusplus } #endif // Define _W64 macros to mark types changing their size, like intptr_t. #ifndef _W64 # if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 # define _W64 __w64 # else # define _W64 # endif #endif // 7.18.1 Integer types // 7.18.1.1 Exact-width integer types // Visual Studio 6 and Embedded Visual C++ 4 doesn't // realize that, e.g. char has the same size as __int8 // so we give up on __intX for them. #if (_MSC_VER < 1300) typedef signed char int8_t; typedef signed short int16_t; typedef signed int int32_t; typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned int uint32_t; #else typedef signed __int8 int8_t; typedef signed __int16 int16_t; typedef signed __int32 int32_t; typedef unsigned __int8 uint8_t; typedef unsigned __int16 uint16_t; typedef unsigned __int32 uint32_t; #endif typedef signed __int64 int64_t; typedef unsigned __int64 uint64_t; // 7.18.1.2 Minimum-width integer types typedef int8_t int_least8_t; typedef int16_t int_least16_t; typedef int32_t int_least32_t; typedef int64_t int_least64_t; typedef uint8_t uint_least8_t; typedef uint16_t uint_least16_t; typedef uint32_t uint_least32_t; typedef uint64_t uint_least64_t; // 7.18.1.3 Fastest minimum-width integer types typedef int8_t int_fast8_t; typedef int16_t int_fast16_t; typedef int32_t int_fast32_t; typedef int64_t int_fast64_t; typedef uint8_t uint_fast8_t; typedef uint16_t uint_fast16_t; typedef uint32_t uint_fast32_t; typedef uint64_t uint_fast64_t; // 7.18.1.4 Integer types capable of holding object pointers #ifdef _WIN64 // [ typedef signed __int64 intptr_t; typedef unsigned __int64 uintptr_t; #else // _WIN64 ][ typedef _W64 signed int intptr_t; typedef _W64 unsigned int uintptr_t; #endif // _WIN64 ] // 7.18.1.5 Greatest-width integer types typedef int64_t intmax_t; typedef uint64_t uintmax_t; // 7.18.2 Limits of specified-width integer types #if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 // 7.18.2.1 Limits of exact-width integer types #define INT8_MIN ((int8_t)_I8_MIN) #define INT8_MAX _I8_MAX #define INT16_MIN ((int16_t)_I16_MIN) #define INT16_MAX _I16_MAX #define INT32_MIN ((int32_t)_I32_MIN) #define INT32_MAX _I32_MAX #define INT64_MIN ((int64_t)_I64_MIN) #define INT64_MAX _I64_MAX #define UINT8_MAX _UI8_MAX #define UINT16_MAX _UI16_MAX #define UINT32_MAX _UI32_MAX #define UINT64_MAX _UI64_MAX // 7.18.2.2 Limits of minimum-width integer types #define INT_LEAST8_MIN INT8_MIN #define INT_LEAST8_MAX INT8_MAX #define INT_LEAST16_MIN INT16_MIN #define INT_LEAST16_MAX INT16_MAX #define INT_LEAST32_MIN INT32_MIN #define INT_LEAST32_MAX INT32_MAX #define INT_LEAST64_MIN INT64_MIN #define INT_LEAST64_MAX INT64_MAX #define UINT_LEAST8_MAX UINT8_MAX #define UINT_LEAST16_MAX UINT16_MAX #define UINT_LEAST32_MAX UINT32_MAX #define UINT_LEAST64_MAX UINT64_MAX // 7.18.2.3 Limits of fastest minimum-width integer types #define INT_FAST8_MIN INT8_MIN #define INT_FAST8_MAX INT8_MAX #define INT_FAST16_MIN INT16_MIN #define INT_FAST16_MAX INT16_MAX #define INT_FAST32_MIN INT32_MIN #define INT_FAST32_MAX INT32_MAX #define INT_FAST64_MIN INT64_MIN #define INT_FAST64_MAX INT64_MAX #define UINT_FAST8_MAX UINT8_MAX #define UINT_FAST16_MAX UINT16_MAX #define UINT_FAST32_MAX UINT32_MAX #define UINT_FAST64_MAX UINT64_MAX // 7.18.2.4 Limits of integer types capable of holding object pointers #ifdef _WIN64 // [ # define INTPTR_MIN INT64_MIN # define INTPTR_MAX INT64_MAX # define UINTPTR_MAX UINT64_MAX #else // _WIN64 ][ # define INTPTR_MIN INT32_MIN # define INTPTR_MAX INT32_MAX # define UINTPTR_MAX UINT32_MAX #endif // _WIN64 ] // 7.18.2.5 Limits of greatest-width integer types #define INTMAX_MIN INT64_MIN #define INTMAX_MAX INT64_MAX #define UINTMAX_MAX UINT64_MAX // 7.18.3 Limits of other integer types #ifdef _WIN64 // [ # define PTRDIFF_MIN _I64_MIN # define PTRDIFF_MAX _I64_MAX #else // _WIN64 ][ # define PTRDIFF_MIN _I32_MIN # define PTRDIFF_MAX _I32_MAX #endif // _WIN64 ] #define SIG_ATOMIC_MIN INT_MIN #define SIG_ATOMIC_MAX INT_MAX #ifndef SIZE_MAX // [ # ifdef _WIN64 // [ # define SIZE_MAX _UI64_MAX # else // _WIN64 ][ # define SIZE_MAX _UI32_MAX # endif // _WIN64 ] #endif // SIZE_MAX ] // WCHAR_MIN and WCHAR_MAX are also defined in #ifndef WCHAR_MIN // [ # define WCHAR_MIN 0 #endif // WCHAR_MIN ] #ifndef WCHAR_MAX // [ # define WCHAR_MAX _UI16_MAX #endif // WCHAR_MAX ] #define WINT_MIN 0 #define WINT_MAX _UI16_MAX #endif // __STDC_LIMIT_MACROS ] // 7.18.4 Limits of other integer types #if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 // 7.18.4.1 Macros for minimum-width integer constants #define INT8_C(val) val##i8 #define INT16_C(val) val##i16 #define INT32_C(val) val##i32 #define INT64_C(val) val##i64 #define UINT8_C(val) val##ui8 #define UINT16_C(val) val##ui16 #define UINT32_C(val) val##ui32 #define UINT64_C(val) val##ui64 // 7.18.4.2 Macros for greatest-width integer constants // These #ifndef's are needed to prevent collisions with . // Check out Issue 9 for the details. #ifndef INTMAX_C // [ # define INTMAX_C INT64_C #endif // INTMAX_C ] #ifndef UINTMAX_C // [ # define UINTMAX_C UINT64_C #endif // UINTMAX_C ] #endif // __STDC_CONSTANT_MACROS ] #endif // _MSC_VER >= 1600 ] #endif // _MSC_STDINT_H_ ] mongodb-1.1.5/src/libbson/src/bson/bson-stdint.h0000664000175000017500000000111212673034026021365 0ustar jmikolajmikola#ifndef ___SRC_LIBBSON_SRC_BSON_BSON_STDINT_H #define ___SRC_LIBBSON_SRC_BSON_BSON_STDINT_H 1 #ifndef _GENERATED_STDINT_H #define _GENERATED_STDINT_H " " /* generated using a gnu compiler version cc (Ubuntu 5.2.1-22ubuntu2) 5.2.1 20151010 Copyright (C) 2015 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ #include /* system headers have good uint64_t */ #ifndef _HAVE_UINT64_T #define _HAVE_UINT64_T #endif /* once */ #endif #endif mongodb-1.1.5/src/libbson/src/bson/bson-string.c0000664000175000017500000003703512673034026021376 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include "bson-compat.h" #include "bson-config.h" #include "bson-string.h" #include "bson-memory.h" #include "bson-utf8.h" /* *-------------------------------------------------------------------------- * * bson_string_new -- * * Create a new bson_string_t. * * bson_string_t is a power-of-2 allocation growing string. Every * time data is appended the next power of two size is chosen for * the allocation. Pretty standard stuff. * * It is UTF-8 aware through the use of bson_string_append_unichar(). * The proper UTF-8 character sequence will be used. * * Parameters: * @str: a string to copy or NULL. * * Returns: * A newly allocated bson_string_t that should be freed with * bson_string_free(). * * Side effects: * None. * *-------------------------------------------------------------------------- */ bson_string_t * bson_string_new (const char *str) /* IN */ { bson_string_t *ret; ret = bson_malloc0 (sizeof *ret); ret->len = str ? (int)strlen (str) : 0; ret->alloc = ret->len + 1; if (!bson_is_power_of_two (ret->alloc)) { ret->alloc = (uint32_t)bson_next_power_of_two ((size_t)ret->alloc); } BSON_ASSERT (ret->alloc >= 1); ret->str = bson_malloc (ret->alloc); if (str) { memcpy (ret->str, str, ret->len); } ret->str [ret->len] = '\0'; ret->str [ret->len] = '\0'; return ret; } /* *-------------------------------------------------------------------------- * * bson_string_free -- * * Free the bson_string_t @string and related allocations. * * If @free_segment is false, then the strings buffer will be * returned and is not freed. Otherwise, NULL is returned. * * Returns: * The string->str if free_segment is false. * Otherwise NULL. * * Side effects: * None. * *-------------------------------------------------------------------------- */ char * bson_string_free (bson_string_t *string, /* IN */ bool free_segment) /* IN */ { char *ret = NULL; BSON_ASSERT (string); if (!free_segment) { ret = string->str; } else { bson_free (string->str); } bson_free (string); return ret; } /* *-------------------------------------------------------------------------- * * bson_string_append -- * * Append the UTF-8 string @str to @string. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void bson_string_append (bson_string_t *string, /* IN */ const char *str) /* IN */ { uint32_t len; BSON_ASSERT (string); BSON_ASSERT (str); len = (uint32_t)strlen (str); if ((string->alloc - string->len - 1) < len) { string->alloc += len; if (!bson_is_power_of_two (string->alloc)) { string->alloc = (uint32_t)bson_next_power_of_two ((size_t)string->alloc); } string->str = bson_realloc (string->str, string->alloc); } memcpy (string->str + string->len, str, len); string->len += len; string->str [string->len] = '\0'; } /* *-------------------------------------------------------------------------- * * bson_string_append_c -- * * Append the ASCII character @c to @string. * * Do not use this if you are working with UTF-8 sequences, * use bson_string_append_unichar(). * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void bson_string_append_c (bson_string_t *string, /* IN */ char c) /* IN */ { char cc[2]; BSON_ASSERT (string); if (BSON_UNLIKELY (string->alloc == (string->len + 1))) { cc [0] = c; cc [1] = '\0'; bson_string_append (string, cc); return; } string->str [string->len++] = c; string->str [string->len] = '\0'; } /* *-------------------------------------------------------------------------- * * bson_string_append_unichar -- * * Append the bson_unichar_t @unichar to the string @string. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void bson_string_append_unichar (bson_string_t *string, /* IN */ bson_unichar_t unichar) /* IN */ { uint32_t len; char str [8]; BSON_ASSERT (string); BSON_ASSERT (unichar); bson_utf8_from_unichar (unichar, str, &len); if (len <= 6) { str [len] = '\0'; bson_string_append (string, str); } } /* *-------------------------------------------------------------------------- * * bson_string_append_printf -- * * Format a string according to @format and append it to @string. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void bson_string_append_printf (bson_string_t *string, const char *format, ...) { va_list args; char *ret; BSON_ASSERT (string); BSON_ASSERT (format); va_start (args, format); ret = bson_strdupv_printf (format, args); va_end (args); bson_string_append (string, ret); bson_free (ret); } /* *-------------------------------------------------------------------------- * * bson_string_truncate -- * * Truncate the string @string to @len bytes. * * The underlying memory will be released via realloc() down to * the minimum required size specified by @len. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void bson_string_truncate (bson_string_t *string, /* IN */ uint32_t len) /* IN */ { uint32_t alloc; BSON_ASSERT (string); BSON_ASSERT (len < INT_MAX); alloc = len + 1; if (alloc < 16) { alloc = 16; } if (!bson_is_power_of_two (alloc)) { alloc = (uint32_t)bson_next_power_of_two ((size_t)alloc); } string->str = bson_realloc (string->str, alloc); string->alloc = alloc; string->len = len; string->str [string->len] = '\0'; } /* *-------------------------------------------------------------------------- * * bson_strdup -- * * Portable strdup(). * * Returns: * A newly allocated string that should be freed with bson_free(). * * Side effects: * None. * *-------------------------------------------------------------------------- */ char * bson_strdup (const char *str) /* IN */ { long len; char *out; if (!str) { return NULL; } len = (long)strlen (str); out = bson_malloc (len + 1); if (!out) { return NULL; } memcpy (out, str, len + 1); return out; } /* *-------------------------------------------------------------------------- * * bson_strdupv_printf -- * * Like bson_strdup_printf() but takes a va_list. * * Returns: * A newly allocated string that should be freed with bson_free(). * * Side effects: * None. * *-------------------------------------------------------------------------- */ char * bson_strdupv_printf (const char *format, /* IN */ va_list args) /* IN */ { va_list my_args; char *buf; int len = 32; int n; BSON_ASSERT (format); buf = bson_malloc0 (len); while (true) { va_copy (my_args, args); n = bson_vsnprintf (buf, len, format, my_args); va_end (my_args); if (n > -1 && n < len) { return buf; } if (n > -1) { len = n + 1; } else { len *= 2; } buf = bson_realloc (buf, len); } } /* *-------------------------------------------------------------------------- * * bson_strdup_printf -- * * Convenience function that formats a string according to @format * and returns a copy of it. * * Returns: * A newly created string that should be freed with bson_free(). * * Side effects: * None. * *-------------------------------------------------------------------------- */ char * bson_strdup_printf (const char *format, /* IN */ ...) /* IN */ { va_list args; char *ret; BSON_ASSERT (format); va_start (args, format); ret = bson_strdupv_printf (format, args); va_end (args); return ret; } /* *-------------------------------------------------------------------------- * * bson_strndup -- * * A portable strndup(). * * Returns: * A newly allocated string that should be freed with bson_free(). * * Side effects: * None. * *-------------------------------------------------------------------------- */ char * bson_strndup (const char *str, /* IN */ size_t n_bytes) /* IN */ { char *ret; BSON_ASSERT (str); ret = bson_malloc (n_bytes + 1); memcpy (ret, str, n_bytes); ret[n_bytes] = '\0'; return ret; } /* *-------------------------------------------------------------------------- * * bson_strfreev -- * * Frees each string in a NULL terminated array of strings. * This also frees the underlying array. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void bson_strfreev (char **str) /* IN */ { int i; if (str) { for (i = 0; str [i]; i++) bson_free (str [i]); bson_free (str); } } /* *-------------------------------------------------------------------------- * * bson_strnlen -- * * A portable strnlen(). * * Returns: * The length of @s up to @maxlen. * * Side effects: * None. * *-------------------------------------------------------------------------- */ size_t bson_strnlen (const char *s, /* IN */ size_t maxlen) /* IN */ { #ifdef BSON_HAVE_STRNLEN return strnlen (s, maxlen); #else size_t i; for (i = 0; i < maxlen; i++) { if (s [i] == '\0') { return i; } } return maxlen; #endif } /* *-------------------------------------------------------------------------- * * bson_strncpy -- * * A portable strncpy. * * Copies @src into @dst, which must be @size bytes or larger. * The result is guaranteed to be \0 terminated. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void bson_strncpy (char *dst, /* IN */ const char *src, /* IN */ size_t size) /* IN */ { #ifdef _MSC_VER strncpy_s (dst, size, src, _TRUNCATE); #else strncpy (dst, src, size); dst[size - 1] = '\0'; #endif } /* *-------------------------------------------------------------------------- * * bson_vsnprintf -- * * A portable vsnprintf. * * If more than @size bytes are required (exluding the null byte), * then @size bytes will be written to @string and the return value * is the number of bytes required. * * This function will always return a NULL terminated string. * * Returns: * The number of bytes required for @format excluding the null byte. * * Side effects: * @str is initialized with the formatted string. * *-------------------------------------------------------------------------- */ int bson_vsnprintf (char *str, /* IN */ size_t size, /* IN */ const char *format, /* IN */ va_list ap) /* IN */ { #ifdef BSON_OS_WIN32 int r = -1; BSON_ASSERT (str); if (size != 0) { r = _vsnprintf_s (str, size, _TRUNCATE, format, ap); } if (r == -1) { r = _vscprintf (format, ap); } str [size - 1] = '\0'; return r; #else int r; r = vsnprintf (str, size, format, ap); str [size - 1] = '\0'; return r; #endif } /* *-------------------------------------------------------------------------- * * bson_snprintf -- * * A portable snprintf. * * If @format requires more than @size bytes, then @size bytes are * written and the result is the number of bytes required (excluding * the null byte). * * This function will always return a NULL terminated string. * * Returns: * The number of bytes required for @format. * * Side effects: * @str is initialized. * *-------------------------------------------------------------------------- */ int bson_snprintf (char *str, /* IN */ size_t size, /* IN */ const char *format, /* IN */ ...) { int r; va_list ap; BSON_ASSERT (str); va_start (ap, format); r = bson_vsnprintf (str, size, format, ap); va_end (ap); return r; } int64_t bson_ascii_strtoll (const char *s, char **e, int base) { char *tok = (char *)s; char c; int64_t number = 0; int64_t sign = 1; if (!s) { errno = EINVAL; return 0; } c = *tok; while (isspace (c)) { c = *++tok; } if (!isdigit (c) && (c != '+') && (c != '-')) { *e = tok - 1; errno = EINVAL; return 0; } if (c == '-') { sign = -1; c = *++tok; } if (c == '+') { c = *++tok; } if (c == '0' && tok[1] != '\0') { /* Hex, octal or binary -- maybe. */ c = *++tok; if (c == 'x' || c == 'X') { /* Hex */ if (base != 16) { *e = (char *)(s); errno = EINVAL; return 0; } c = *++tok; if (!isxdigit (c)) { *e = tok; errno = EINVAL; return 0; } do { number = (number << 4) + (c - '0'); c = *(++tok); } while (isxdigit (c)); } else { /* Octal */ if (base != 8) { *e = (char *)(s); errno = EINVAL; return 0; } if (c < '0' || c >= '8') { *e = tok; errno = EINVAL; return 0; } do { number = (number << 3) + (c - '0'); c = *(++tok); } while (('0' <= c) && (c < '8')); } while (c == 'l' || c == 'L' || c == 'u' || c == 'U') { c = *++tok; } } else { /* Decimal */ if (base != 10) { *e = (char *)(s); errno = EINVAL; return 0; } do { number = (number * 10) + (c - '0'); c = *(++tok); } while (isdigit (c)); while (c == 'l' || c == 'L' || c == 'u' || c == 'U') { c = *(++tok); } } *e = tok; errno = 0; return (sign * number); } mongodb-1.1.5/src/libbson/src/bson/bson-string.h0000664000175000017500000000677412673034026021411 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef BSON_STRING_H #define BSON_STRING_H #if !defined (BSON_INSIDE) && !defined (BSON_COMPILATION) # error "Only can be included directly." #endif #include #include "bson-macros.h" #include "bson-types.h" BSON_BEGIN_DECLS typedef struct { char *str; uint32_t len; uint32_t alloc; } bson_string_t; bson_string_t *bson_string_new (const char *str); char *bson_string_free (bson_string_t *string, bool free_segment); void bson_string_append (bson_string_t *string, const char *str); void bson_string_append_c (bson_string_t *string, char str); void bson_string_append_unichar (bson_string_t *string, bson_unichar_t unichar); void bson_string_append_printf (bson_string_t *string, const char *format, ...) BSON_GNUC_PRINTF (2, 3); void bson_string_truncate (bson_string_t *string, uint32_t len); char *bson_strdup (const char *str); char *bson_strdup_printf (const char *format, ...) BSON_GNUC_PRINTF (1, 2); char *bson_strdupv_printf (const char *format, va_list args) BSON_GNUC_PRINTF (1, 0); char *bson_strndup (const char *str, size_t n_bytes); void bson_strncpy (char *dst, const char *src, size_t size); int bson_vsnprintf (char *str, size_t size, const char *format, va_list ap) BSON_GNUC_PRINTF (3, 0); int bson_snprintf (char *str, size_t size, const char *format, ...) BSON_GNUC_PRINTF (3, 4); void bson_strfreev (char **strv); size_t bson_strnlen (const char *s, size_t maxlen); int64_t bson_ascii_strtoll (const char *str, char **endptr, int base); BSON_END_DECLS #endif /* BSON_STRING_H */ mongodb-1.1.5/src/libbson/src/bson/bson-thread-private.h0000664000175000017500000000537712673034026023020 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef BSON_THREAD_PRIVATE_H #define BSON_THREAD_PRIVATE_H #if !defined (BSON_INSIDE) && !defined (BSON_COMPILATION) # error "Only can be included directly." #endif #include "bson-compat.h" #include "bson-config.h" #include "bson-macros.h" BSON_BEGIN_DECLS #if defined(BSON_OS_UNIX) # include # define bson_mutex_t pthread_mutex_t # define bson_mutex_init(_n) pthread_mutex_init((_n), NULL) # define bson_mutex_lock pthread_mutex_lock # define bson_mutex_unlock pthread_mutex_unlock # define bson_mutex_destroy pthread_mutex_destroy # define bson_thread_t pthread_t # define bson_thread_create(_t,_f,_d) pthread_create((_t), NULL, (_f), (_d)) # define bson_thread_join(_n) pthread_join((_n), NULL) # define bson_once_t pthread_once_t # define bson_once pthread_once # define BSON_ONCE_FUN(n) void n(void) # define BSON_ONCE_RETURN return # ifdef BSON_PTHREAD_ONCE_INIT_NEEDS_BRACES # define BSON_ONCE_INIT {PTHREAD_ONCE_INIT} # else # define BSON_ONCE_INIT PTHREAD_ONCE_INIT # endif #else # define bson_mutex_t CRITICAL_SECTION # define bson_mutex_init InitializeCriticalSection # define bson_mutex_lock EnterCriticalSection # define bson_mutex_unlock LeaveCriticalSection # define bson_mutex_destroy DeleteCriticalSection # define bson_thread_t HANDLE # define bson_thread_create(_t,_f,_d) (!(*(_t) = CreateThread(NULL,0,(void*)_f,_d,0,NULL))) # define bson_thread_join(_n) WaitForSingleObject((_n), INFINITE) # define bson_once_t INIT_ONCE # define BSON_ONCE_INIT INIT_ONCE_STATIC_INIT # define bson_once(o, c) InitOnceExecuteOnce(o, c, NULL, NULL) # define BSON_ONCE_FUN(n) BOOL CALLBACK n(PINIT_ONCE _ignored_a, PVOID _ignored_b, PVOID *_ignored_c) # define BSON_ONCE_RETURN return true #endif BSON_END_DECLS #endif /* BSON_THREAD_PRIVATE_H */ mongodb-1.1.5/src/libbson/src/bson/bson-timegm-private.h0000664000175000017500000000147212673034026023023 0ustar jmikolajmikola/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef BSON_TIMEGM_PRIVATE_H #define BSON_TIMEGM_PRIVATE_H #include "bson-compat.h" #include "bson-macros.h" BSON_BEGIN_DECLS time_t _bson_timegm (struct tm *const tmp); BSON_END_DECLS #endif /* BSON_TIMEGM_PRIVATE_H */ mongodb-1.1.5/src/libbson/src/bson/bson-timegm.c0000664000175000017500000005161112673034026021346 0ustar jmikolajmikola/* ** This file is in the public domain, so clarified as of ** 1996-06-05 by Arthur David Olson. */ /* ** Leap second handling from Bradley White. ** POSIX-style TZ environment variable handling from Guy Harris. */ #include "bson-compat.h" #include "bson-macros.h" #include "bson-timegm-private.h" #ifndef BSON_OS_WIN32 #include "errno.h" #include "string.h" #include "limits.h" /* for CHAR_BIT et al. */ #include "time.h" /* Unlike 's isdigit, this also works if c < 0 | c > UCHAR_MAX. */ #define is_digit(c) ((unsigned)(c) - '0' <= 9) #ifndef CHAR_BIT #define CHAR_BIT 8 #endif #if 2 < __GNUC__ + (96 <= __GNUC_MINOR__) # define ATTRIBUTE_CONST __attribute__ ((const)) # define ATTRIBUTE_PURE __attribute__ ((__pure__)) # define ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec)) #else # define ATTRIBUTE_CONST /* empty */ # define ATTRIBUTE_PURE /* empty */ # define ATTRIBUTE_FORMAT(spec) /* empty */ #endif #if !defined _Noreturn && (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 201112) # if 2 < __GNUC__ + (8 <= __GNUC_MINOR__) # define _Noreturn __attribute__ ((__noreturn__)) # else # define _Noreturn # endif #endif #if (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901) && !defined restrict # define restrict /* empty */ #endif #ifndef TYPE_BIT #define TYPE_BIT(type) (sizeof (type) * CHAR_BIT) #endif /* !defined TYPE_BIT */ #ifndef TYPE_SIGNED #define TYPE_SIGNED(type) (((type) -1) < 0) #endif /* !defined TYPE_SIGNED */ /* The minimum and maximum finite time values. */ static time_t const time_t_min = (TYPE_SIGNED(time_t) ? (time_t) -1 << (CHAR_BIT * sizeof (time_t) - 1) : 0); static time_t const time_t_max = (TYPE_SIGNED(time_t) ? - (~ 0 < 0) - ((time_t) -1 << (CHAR_BIT * sizeof (time_t) - 1)) : -1); #ifndef TZ_MAX_TIMES #define TZ_MAX_TIMES 2000 #endif /* !defined TZ_MAX_TIMES */ #ifndef TZ_MAX_TYPES /* This must be at least 17 for Europe/Samara and Europe/Vilnius. */ #define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */ #endif /* !defined TZ_MAX_TYPES */ #ifndef TZ_MAX_CHARS #define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */ /* (limited by what unsigned chars can hold) */ #endif /* !defined TZ_MAX_CHARS */ #ifndef TZ_MAX_LEAPS #define TZ_MAX_LEAPS 50 /* Maximum number of leap second corrections */ #endif /* !defined TZ_MAX_LEAPS */ #define SECSPERMIN 60 #define MINSPERHOUR 60 #define HOURSPERDAY 24 #define DAYSPERWEEK 7 #define DAYSPERNYEAR 365 #define DAYSPERLYEAR 366 #define SECSPERHOUR (SECSPERMIN * MINSPERHOUR) #define SECSPERDAY ((int_fast32_t) SECSPERHOUR * HOURSPERDAY) #define MONSPERYEAR 12 #define TM_SUNDAY 0 #define TM_MONDAY 1 #define TM_TUESDAY 2 #define TM_WEDNESDAY 3 #define TM_THURSDAY 4 #define TM_FRIDAY 5 #define TM_SATURDAY 6 #define TM_JANUARY 0 #define TM_FEBRUARY 1 #define TM_MARCH 2 #define TM_APRIL 3 #define TM_MAY 4 #define TM_JUNE 5 #define TM_JULY 6 #define TM_AUGUST 7 #define TM_SEPTEMBER 8 #define TM_OCTOBER 9 #define TM_NOVEMBER 10 #define TM_DECEMBER 11 #define TM_YEAR_BASE 1900 #define EPOCH_YEAR 1970 #define EPOCH_WDAY TM_THURSDAY #define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0)) /* ** Since everything in isleap is modulo 400 (or a factor of 400), we know that ** isleap(y) == isleap(y % 400) ** and so ** isleap(a + b) == isleap((a + b) % 400) ** or ** isleap(a + b) == isleap(a % 400 + b % 400) ** This is true even if % means modulo rather than Fortran remainder ** (which is allowed by C89 but not C99). ** We use this to avoid addition overflow problems. */ #define isleap_sum(a, b) isleap((a) % 400 + (b) % 400) #ifndef TZ_ABBR_MAX_LEN #define TZ_ABBR_MAX_LEN 16 #endif /* !defined TZ_ABBR_MAX_LEN */ #ifndef TZ_ABBR_CHAR_SET #define TZ_ABBR_CHAR_SET \ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :+-._" #endif /* !defined TZ_ABBR_CHAR_SET */ #ifndef TZ_ABBR_ERR_CHAR #define TZ_ABBR_ERR_CHAR '_' #endif /* !defined TZ_ABBR_ERR_CHAR */ #ifndef WILDABBR /* ** Someone might make incorrect use of a time zone abbreviation: ** 1. They might reference tzname[0] before calling tzset (explicitly ** or implicitly). ** 2. They might reference tzname[1] before calling tzset (explicitly ** or implicitly). ** 3. They might reference tzname[1] after setting to a time zone ** in which Daylight Saving Time is never observed. ** 4. They might reference tzname[0] after setting to a time zone ** in which Standard Time is never observed. ** 5. They might reference tm.TM_ZONE after calling offtime. ** What's best to do in the above cases is open to debate; ** for now, we just set things up so that in any of the five cases ** WILDABBR is used. Another possibility: initialize tzname[0] to the ** string "tzname[0] used before set", and similarly for the other cases. ** And another: initialize tzname[0] to "ERA", with an explanation in the ** manual page of what this "time zone abbreviation" means (doing this so ** that tzname[0] has the "normal" length of three characters). */ #define WILDABBR " " #endif /* !defined WILDABBR */ #ifdef TM_ZONE static const char wildabbr[] = WILDABBR; #endif static const char gmt[] = "GMT"; struct ttinfo { /* time type information */ int_fast32_t tt_gmtoff; /* UT offset in seconds */ int tt_isdst; /* used to set tm_isdst */ int tt_abbrind; /* abbreviation list index */ int tt_ttisstd; /* true if transition is std time */ int tt_ttisgmt; /* true if transition is UT */ }; struct lsinfo { /* leap second information */ time_t ls_trans; /* transition time */ int_fast64_t ls_corr; /* correction to apply */ }; #define BIGGEST(a, b) (((a) > (b)) ? (a) : (b)) #ifdef TZNAME_MAX #define MY_TZNAME_MAX TZNAME_MAX #endif /* defined TZNAME_MAX */ #ifndef TZNAME_MAX #define MY_TZNAME_MAX 255 #endif /* !defined TZNAME_MAX */ struct state { int leapcnt; int timecnt; int typecnt; int charcnt; int goback; int goahead; time_t ats[TZ_MAX_TIMES]; unsigned char types[TZ_MAX_TIMES]; struct ttinfo ttis[TZ_MAX_TYPES]; char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS + 1, sizeof gmt), (2 * (MY_TZNAME_MAX + 1)))]; struct lsinfo lsis[TZ_MAX_LEAPS]; int defaulttype; /* for early times or if no transitions */ }; struct rule { int r_type; /* type of rule--see below */ int r_day; /* day number of rule */ int r_week; /* week number of rule */ int r_mon; /* month number of rule */ int_fast32_t r_time; /* transition time of rule */ }; #define JULIAN_DAY 0 /* Jn - Julian day */ #define DAY_OF_YEAR 1 /* n - day of year */ #define MONTH_NTH_DAY_OF_WEEK 2 /* Mm.n.d - month, week, day of week */ /* ** Prototypes for static functions. */ static void gmtload(struct state * sp); static struct tm * gmtsub(const time_t * timep, int_fast32_t offset, struct tm * tmp); static int increment_overflow(int * number, int delta); static int leaps_thru_end_of(int y) ATTRIBUTE_PURE; static int increment_overflow32(int_fast32_t * number, int delta); static int normalize_overflow32(int_fast32_t * tensptr, int * unitsptr, int base); static int normalize_overflow(int * tensptr, int * unitsptr, int base); static time_t time1(struct tm * tmp, struct tm * (*funcp)(const time_t *, int_fast32_t, struct tm *), int_fast32_t offset); static time_t time2(struct tm *tmp, struct tm * (*funcp)(const time_t *, int_fast32_t, struct tm*), int_fast32_t offset, int * okayp); static time_t time2sub(struct tm *tmp, struct tm * (*funcp)(const time_t *, int_fast32_t, struct tm*), int_fast32_t offset, int * okayp, int do_norm_secs); static struct tm * timesub(const time_t * timep, int_fast32_t offset, const struct state * sp, struct tm * tmp); static int tmcomp(const struct tm * atmp, const struct tm * btmp); static struct state gmtmem; #define gmtptr (&gmtmem) static int gmt_is_set; static const int mon_lengths[2][MONSPERYEAR] = { { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } }; static const int year_lengths[2] = { DAYSPERNYEAR, DAYSPERLYEAR }; static void gmtload(struct state *const sp) { memset(sp, 0, sizeof(struct state)); sp->typecnt = 1; sp->charcnt = 4; sp->chars[0] = 'G'; sp->chars[1] = 'M'; sp->chars[2] = 'T'; } /* ** gmtsub is to gmtime as localsub is to localtime. */ static struct tm * gmtsub(const time_t *const timep, const int_fast32_t offset, struct tm *const tmp) { register struct tm * result; if (!gmt_is_set) { gmt_is_set = true; // if (gmtptr != NULL) gmtload(gmtptr); } result = timesub(timep, offset, gmtptr, tmp); #ifdef TM_ZONE /* ** Could get fancy here and deliver something such as ** "UT+xxxx" or "UT-xxxx" if offset is non-zero, ** but this is no time for a treasure hunt. */ tmp->TM_ZONE = offset ? wildabbr : gmtptr ? gmtptr->chars : gmt; #endif /* defined TM_ZONE */ return result; } /* ** Return the number of leap years through the end of the given year ** where, to make the math easy, the answer for year zero is defined as zero. */ static int leaps_thru_end_of(register const int y) { return (y >= 0) ? (y / 4 - y / 100 + y / 400) : -(leaps_thru_end_of(-(y + 1)) + 1); } static struct tm * timesub(const time_t *const timep, const int_fast32_t offset, register const struct state *const sp, register struct tm *const tmp) { register const struct lsinfo * lp; register time_t tdays; register int idays; /* unsigned would be so 2003 */ register int_fast64_t rem; int y; register const int * ip; register int_fast64_t corr; register int hit; register int i; corr = 0; hit = 0; i = (sp == NULL) ? 0 : sp->leapcnt; while (--i >= 0) { lp = &sp->lsis[i]; if (*timep >= lp->ls_trans) { if (*timep == lp->ls_trans) { hit = ((i == 0 && lp->ls_corr > 0) || lp->ls_corr > sp->lsis[i - 1].ls_corr); if (hit) while (i > 0 && sp->lsis[i].ls_trans == sp->lsis[i - 1].ls_trans + 1 && sp->lsis[i].ls_corr == sp->lsis[i - 1].ls_corr + 1) { ++hit; --i; } } corr = lp->ls_corr; break; } } y = EPOCH_YEAR; tdays = *timep / SECSPERDAY; rem = *timep - tdays * SECSPERDAY; while (tdays < 0 || tdays >= year_lengths[isleap(y)]) { int newy; register time_t tdelta; register int idelta; register int leapdays; tdelta = tdays / DAYSPERLYEAR; if (! ((! TYPE_SIGNED(time_t) || INT_MIN <= tdelta) && tdelta <= INT_MAX)) return NULL; idelta = (int) tdelta; if (idelta == 0) idelta = (tdays < 0) ? -1 : 1; newy = y; if (increment_overflow(&newy, idelta)) return NULL; leapdays = leaps_thru_end_of(newy - 1) - leaps_thru_end_of(y - 1); tdays -= ((time_t) newy - y) * DAYSPERNYEAR; tdays -= leapdays; y = newy; } { register int_fast32_t seconds; seconds = (int_fast32_t) (tdays * SECSPERDAY); tdays = seconds / SECSPERDAY; rem += seconds - tdays * SECSPERDAY; } /* ** Given the range, we can now fearlessly cast... */ idays = (int) tdays; rem += offset - corr; while (rem < 0) { rem += SECSPERDAY; --idays; } while (rem >= SECSPERDAY) { rem -= SECSPERDAY; ++idays; } while (idays < 0) { if (increment_overflow(&y, -1)) return NULL; idays += year_lengths[isleap(y)]; } while (idays >= year_lengths[isleap(y)]) { idays -= year_lengths[isleap(y)]; if (increment_overflow(&y, 1)) return NULL; } tmp->tm_year = y; if (increment_overflow(&tmp->tm_year, -TM_YEAR_BASE)) return NULL; tmp->tm_yday = idays; /* ** The "extra" mods below avoid overflow problems. */ tmp->tm_wday = EPOCH_WDAY + ((y - EPOCH_YEAR) % DAYSPERWEEK) * (DAYSPERNYEAR % DAYSPERWEEK) + leaps_thru_end_of(y - 1) - leaps_thru_end_of(EPOCH_YEAR - 1) + idays; tmp->tm_wday %= DAYSPERWEEK; if (tmp->tm_wday < 0) tmp->tm_wday += DAYSPERWEEK; tmp->tm_hour = (int) (rem / SECSPERHOUR); rem %= SECSPERHOUR; tmp->tm_min = (int) (rem / SECSPERMIN); /* ** A positive leap second requires a special ** representation. This uses "... ??:59:60" et seq. */ tmp->tm_sec = (int) (rem % SECSPERMIN) + hit; ip = mon_lengths[isleap(y)]; for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon)) idays -= ip[tmp->tm_mon]; tmp->tm_mday = (int) (idays + 1); tmp->tm_isdst = 0; #ifdef TM_GMTOFF tmp->TM_GMTOFF = offset; #endif /* defined TM_GMTOFF */ return tmp; } /* ** Adapted from code provided by Robert Elz, who writes: ** The "best" way to do mktime I think is based on an idea of Bob ** Kridle's (so its said...) from a long time ago. ** It does a binary search of the time_t space. Since time_t's are ** just 32 bits, its a max of 32 iterations (even at 64 bits it ** would still be very reasonable). */ #ifndef WRONG #define WRONG (-1) #endif /* !defined WRONG */ /* ** Normalize logic courtesy Paul Eggert. */ static int increment_overflow(int *const ip, int j) { register int const i = *ip; /* ** If i >= 0 there can only be overflow if i + j > INT_MAX ** or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow. ** If i < 0 there can only be overflow if i + j < INT_MIN ** or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow. */ if ((i >= 0) ? (j > INT_MAX - i) : (j < INT_MIN - i)) return true; *ip += j; return false; } static int increment_overflow32(int_fast32_t *const lp, int const m) { register int_fast32_t const l = *lp; if ((l >= 0) ? (m > INT_FAST32_MAX - l) : (m < INT_FAST32_MIN - l)) return true; *lp += m; return false; } static int normalize_overflow(int *const tensptr, int *const unitsptr, const int base) { register int tensdelta; tensdelta = (*unitsptr >= 0) ? (*unitsptr / base) : (-1 - (-1 - *unitsptr) / base); *unitsptr -= tensdelta * base; return increment_overflow(tensptr, tensdelta); } static int normalize_overflow32(int_fast32_t *const tensptr, int *const unitsptr, const int base) { register int tensdelta; tensdelta = (*unitsptr >= 0) ? (*unitsptr / base) : (-1 - (-1 - *unitsptr) / base); *unitsptr -= tensdelta * base; return increment_overflow32(tensptr, tensdelta); } static int tmcomp(register const struct tm *const atmp, register const struct tm *const btmp) { register int result; if (atmp->tm_year != btmp->tm_year) return atmp->tm_year < btmp->tm_year ? -1 : 1; if ((result = (atmp->tm_mon - btmp->tm_mon)) == 0 && (result = (atmp->tm_mday - btmp->tm_mday)) == 0 && (result = (atmp->tm_hour - btmp->tm_hour)) == 0 && (result = (atmp->tm_min - btmp->tm_min)) == 0) result = atmp->tm_sec - btmp->tm_sec; return result; } static time_t time2sub(struct tm *const tmp, struct tm *(*const funcp)(const time_t *, int_fast32_t, struct tm *), const int_fast32_t offset, int *const okayp, const int do_norm_secs) { register const struct state * sp; register int dir; register int i, j; register int saved_seconds; register int_fast32_t li; register time_t lo; register time_t hi; int_fast32_t y; time_t newt; time_t t; struct tm yourtm, mytm; *okayp = false; yourtm = *tmp; if (do_norm_secs) { if (normalize_overflow(&yourtm.tm_min, &yourtm.tm_sec, SECSPERMIN)) return WRONG; } if (normalize_overflow(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR)) return WRONG; if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY)) return WRONG; y = yourtm.tm_year; if (normalize_overflow32(&y, &yourtm.tm_mon, MONSPERYEAR)) return WRONG; /* ** Turn y into an actual year number for now. ** It is converted back to an offset from TM_YEAR_BASE later. */ if (increment_overflow32(&y, TM_YEAR_BASE)) return WRONG; while (yourtm.tm_mday <= 0) { if (increment_overflow32(&y, -1)) return WRONG; li = y + (1 < yourtm.tm_mon); yourtm.tm_mday += year_lengths[isleap(li)]; } while (yourtm.tm_mday > DAYSPERLYEAR) { li = y + (1 < yourtm.tm_mon); yourtm.tm_mday -= year_lengths[isleap(li)]; if (increment_overflow32(&y, 1)) return WRONG; } for ( ; ; ) { i = mon_lengths[isleap(y)][yourtm.tm_mon]; if (yourtm.tm_mday <= i) break; yourtm.tm_mday -= i; if (++yourtm.tm_mon >= MONSPERYEAR) { yourtm.tm_mon = 0; if (increment_overflow32(&y, 1)) return WRONG; } } if (increment_overflow32(&y, -TM_YEAR_BASE)) return WRONG; yourtm.tm_year = y; if (yourtm.tm_year != y) return WRONG; if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN) saved_seconds = 0; else if (y + TM_YEAR_BASE < EPOCH_YEAR) { /* ** We can't set tm_sec to 0, because that might push the ** time below the minimum representable time. ** Set tm_sec to 59 instead. ** This assumes that the minimum representable time is ** not in the same minute that a leap second was deleted from, ** which is a safer assumption than using 58 would be. */ if (increment_overflow(&yourtm.tm_sec, 1 - SECSPERMIN)) return WRONG; saved_seconds = yourtm.tm_sec; yourtm.tm_sec = SECSPERMIN - 1; } else { saved_seconds = yourtm.tm_sec; yourtm.tm_sec = 0; } /* ** Do a binary search (this works whatever time_t's type is). */ if (!TYPE_SIGNED(time_t)) { lo = 0; hi = lo - 1; } else { lo = 1; for (i = 0; i < (int) TYPE_BIT(time_t) - 1; ++i) lo *= 2; hi = -(lo + 1); } for ( ; ; ) { t = lo / 2 + hi / 2; if (t < lo) t = lo; else if (t > hi) t = hi; if ((*funcp)(&t, offset, &mytm) == NULL) { /* ** Assume that t is too extreme to be represented in ** a struct tm; arrange things so that it is less ** extreme on the next pass. */ dir = (t > 0) ? 1 : -1; } else dir = tmcomp(&mytm, &yourtm); if (dir != 0) { if (t == lo) { if (t == time_t_max) return WRONG; ++t; ++lo; } else if (t == hi) { if (t == time_t_min) return WRONG; --t; --hi; } if (lo > hi) return WRONG; if (dir > 0) hi = t; else lo = t; continue; } if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst) break; /* ** Right time, wrong type. ** Hunt for right time, right type. ** It's okay to guess wrong since the guess ** gets checked. */ sp = (const struct state *) gmtptr; if (sp == NULL) return WRONG; for (i = sp->typecnt - 1; i >= 0; --i) { if (sp->ttis[i].tt_isdst != yourtm.tm_isdst) continue; for (j = sp->typecnt - 1; j >= 0; --j) { if (sp->ttis[j].tt_isdst == yourtm.tm_isdst) continue; newt = t + sp->ttis[j].tt_gmtoff - sp->ttis[i].tt_gmtoff; if ((*funcp)(&newt, offset, &mytm) == NULL) continue; if (tmcomp(&mytm, &yourtm) != 0) continue; if (mytm.tm_isdst != yourtm.tm_isdst) continue; /* ** We have a match. */ t = newt; goto label; } } return WRONG; } label: newt = t + saved_seconds; if ((newt < t) != (saved_seconds < 0)) return WRONG; t = newt; if ((*funcp)(&t, offset, tmp)) *okayp = true; return t; } static time_t time2(struct tm * const tmp, struct tm * (*const funcp)(const time_t *, int_fast32_t, struct tm *), const int_fast32_t offset, int *const okayp) { time_t t; /* ** First try without normalization of seconds ** (in case tm_sec contains a value associated with a leap second). ** If that fails, try with normalization of seconds. */ t = time2sub(tmp, funcp, offset, okayp, false); return *okayp ? t : time2sub(tmp, funcp, offset, okayp, true); } static time_t time1(struct tm *const tmp, struct tm *(*const funcp) (const time_t *, int_fast32_t, struct tm *), const int_fast32_t offset) { register time_t t; register const struct state * sp; register int samei, otheri; register int sameind, otherind; register int i; register int nseen; int seen[TZ_MAX_TYPES]; int types[TZ_MAX_TYPES]; int okay; if (tmp == NULL) { errno = EINVAL; return WRONG; } if (tmp->tm_isdst > 1) tmp->tm_isdst = 1; t = time2(tmp, funcp, offset, &okay); if (okay) return t; if (tmp->tm_isdst < 0) #ifdef PCTS /* ** POSIX Conformance Test Suite code courtesy Grant Sullivan. */ tmp->tm_isdst = 0; /* reset to std and try again */ #else return t; #endif /* !defined PCTS */ /* ** We're supposed to assume that somebody took a time of one type ** and did some math on it that yielded a "struct tm" that's bad. ** We try to divine the type they started from and adjust to the ** type they need. */ sp = (const struct state *) gmtptr; if (sp == NULL) return WRONG; for (i = 0; i < sp->typecnt; ++i) seen[i] = false; nseen = 0; for (i = sp->timecnt - 1; i >= 0; --i) if (!seen[sp->types[i]]) { seen[sp->types[i]] = true; types[nseen++] = sp->types[i]; } for (sameind = 0; sameind < nseen; ++sameind) { samei = types[sameind]; if (sp->ttis[samei].tt_isdst != tmp->tm_isdst) continue; for (otherind = 0; otherind < nseen; ++otherind) { otheri = types[otherind]; if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst) continue; tmp->tm_sec += sp->ttis[otheri].tt_gmtoff - sp->ttis[samei].tt_gmtoff; tmp->tm_isdst = !tmp->tm_isdst; t = time2(tmp, funcp, offset, &okay); if (okay) return t; tmp->tm_sec -= sp->ttis[otheri].tt_gmtoff - sp->ttis[samei].tt_gmtoff; tmp->tm_isdst = !tmp->tm_isdst; } } return WRONG; } time_t _bson_timegm(struct tm *const tmp) { if (tmp != NULL) tmp->tm_isdst = 0; return time1(tmp, gmtsub, 0L); } #endif mongodb-1.1.5/src/libbson/src/bson/bson-types.h0000664000175000017500000004065512673034026021243 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef BSON_TYPES_H #define BSON_TYPES_H #if !defined (BSON_INSIDE) && !defined (BSON_COMPILATION) #error "Only can be included directly." #endif #include #include #include "bson-macros.h" #include "bson-compat.h" BSON_BEGIN_DECLS /* *-------------------------------------------------------------------------- * * bson_unichar_t -- * * bson_unichar_t provides an unsigned 32-bit type for containing * unicode characters. When iterating UTF-8 sequences, this should * be used to avoid losing the high-bits of non-ascii characters. * * See also: * bson_string_append_unichar() * *-------------------------------------------------------------------------- */ typedef uint32_t bson_unichar_t; /** * bson_context_flags_t: * * This enumeration is used to configure a bson_context_t. * * %BSON_CONTEXT_NONE: Use default options. * %BSON_CONTEXT_THREAD_SAFE: Context will be called from multiple threads. * %BSON_CONTEXT_DISABLE_PID_CACHE: Call getpid() instead of caching the * result of getpid() when initializing the context. * %BSON_CONTEXT_DISABLE_HOST_CACHE: Call gethostname() instead of caching the * result of gethostname() when initializing the context. */ typedef enum { BSON_CONTEXT_NONE = 0, BSON_CONTEXT_THREAD_SAFE = (1 << 0), BSON_CONTEXT_DISABLE_HOST_CACHE = (1 << 1), BSON_CONTEXT_DISABLE_PID_CACHE = (1 << 2), #if defined(__linux__) BSON_CONTEXT_USE_TASK_ID = (1 << 3), #endif } bson_context_flags_t; /** * bson_context_t: * * This structure manages context for the bson library. It handles * configuration for thread-safety and other performance related requirements. * Consumers will create a context and may use multiple under a variety of * situations. * * If your program calls fork(), you should initialize a new bson_context_t * using bson_context_init(). * * If you are using threading, it is suggested that you use a bson_context_t * per thread for best performance. Alternatively, you can initialize the * bson_context_t with BSON_CONTEXT_THREAD_SAFE, although a performance penalty * will be incurred. * * Many functions will require that you provide a bson_context_t such as OID * generation. * * This structure is oqaque in that you cannot see the contents of the * structure. However, it is stack allocatable in that enough padding is * provided in _bson_context_t to hold the structure. */ typedef struct _bson_context_t bson_context_t; /** * bson_t: * * This structure manages a buffer whose contents are a properly formatted * BSON document. You may perform various transforms on the BSON documents. * Additionally, it can be iterated over using bson_iter_t. * * See bson_iter_init() for iterating the contents of a bson_t. * * When building a bson_t structure using the various append functions, * memory allocations may occur. That is performed using power of two * allocations and realloc(). * * See http://bsonspec.org for the BSON document spec. * * This structure is meant to fit in two sequential 64-byte cachelines. */ BSON_ALIGNED_BEGIN (128) typedef struct _bson_t { uint32_t flags; /* Internal flags for the bson_t. */ uint32_t len; /* Length of BSON data. */ uint8_t padding[120]; /* Padding for stack allocation. */ } bson_t BSON_ALIGNED_END (128); /** * BSON_INITIALIZER: * * This macro can be used to initialize a #bson_t structure on the stack * without calling bson_init(). * * |[ * bson_t b = BSON_INITIALIZER; * ]| */ #define BSON_INITIALIZER { 3, 5, { 5 } } BSON_STATIC_ASSERT (sizeof (bson_t) == 128); /** * bson_oid_t: * * This structure contains the binary form of a BSON Object Id as specified * on http://bsonspec.org. If you would like the bson_oid_t in string form * see bson_oid_to_string() or bson_oid_to_string_r(). */ typedef struct { uint8_t bytes[12]; } bson_oid_t; BSON_STATIC_ASSERT (sizeof (bson_oid_t) == 12); /** * bson_validate_flags_t: * * This enumeration is used for validation of BSON documents. It allows * selective control on what you wish to validate. * * %BSON_VALIDATE_NONE: No additional validation occurs. * %BSON_VALIDATE_UTF8: Check that strings are valid UTF-8. * %BSON_VALIDATE_DOLLAR_KEYS: Check that keys do not start with $. * %BSON_VALIDATE_DOT_KEYS: Check that keys do not contain a period. * %BSON_VALIDATE_UTF8_ALLOW_NULL: Allow NUL bytes in UTF-8 text. */ typedef enum { BSON_VALIDATE_NONE = 0, BSON_VALIDATE_UTF8 = (1 << 0), BSON_VALIDATE_DOLLAR_KEYS = (1 << 1), BSON_VALIDATE_DOT_KEYS = (1 << 2), BSON_VALIDATE_UTF8_ALLOW_NULL = (1 << 3), } bson_validate_flags_t; /** * bson_type_t: * * This enumeration contains all of the possible types within a BSON document. * Use bson_iter_type() to fetch the type of a field while iterating over it. */ typedef enum { BSON_TYPE_EOD = 0x00, BSON_TYPE_DOUBLE = 0x01, BSON_TYPE_UTF8 = 0x02, BSON_TYPE_DOCUMENT = 0x03, BSON_TYPE_ARRAY = 0x04, BSON_TYPE_BINARY = 0x05, BSON_TYPE_UNDEFINED = 0x06, BSON_TYPE_OID = 0x07, BSON_TYPE_BOOL = 0x08, BSON_TYPE_DATE_TIME = 0x09, BSON_TYPE_NULL = 0x0A, BSON_TYPE_REGEX = 0x0B, BSON_TYPE_DBPOINTER = 0x0C, BSON_TYPE_CODE = 0x0D, BSON_TYPE_SYMBOL = 0x0E, BSON_TYPE_CODEWSCOPE = 0x0F, BSON_TYPE_INT32 = 0x10, BSON_TYPE_TIMESTAMP = 0x11, BSON_TYPE_INT64 = 0x12, BSON_TYPE_MAXKEY = 0x7F, BSON_TYPE_MINKEY = 0xFF, } bson_type_t; /** * bson_subtype_t: * * This enumeration contains the various subtypes that may be used in a binary * field. See http://bsonspec.org for more information. */ typedef enum { BSON_SUBTYPE_BINARY = 0x00, BSON_SUBTYPE_FUNCTION = 0x01, BSON_SUBTYPE_BINARY_DEPRECATED = 0x02, BSON_SUBTYPE_UUID_DEPRECATED = 0x03, BSON_SUBTYPE_UUID = 0x04, BSON_SUBTYPE_MD5 = 0x05, BSON_SUBTYPE_USER = 0x80, } bson_subtype_t; /* *-------------------------------------------------------------------------- * * bson_value_t -- * * A boxed type to contain various bson_type_t types. * * See also: * bson_value_copy() * bson_value_destroy() * *-------------------------------------------------------------------------- */ BSON_ALIGNED_BEGIN (8) typedef struct _bson_value_t { bson_type_t value_type; int32_t padding; union { bson_oid_t v_oid; int64_t v_int64; int32_t v_int32; int8_t v_int8; double v_double; bool v_bool; int64_t v_datetime; struct { uint32_t timestamp; uint32_t increment; } v_timestamp; struct { char *str; uint32_t len; } v_utf8; struct { uint8_t *data; uint32_t data_len; } v_doc; struct { uint8_t *data; uint32_t data_len; bson_subtype_t subtype; } v_binary; struct { char *regex; char *options; } v_regex; struct { char *collection; uint32_t collection_len; bson_oid_t oid; } v_dbpointer; struct { char *code; uint32_t code_len; } v_code; struct { char *code; uint8_t *scope_data; uint32_t code_len; uint32_t scope_len; } v_codewscope; struct { char *symbol; uint32_t len; } v_symbol; } value; } bson_value_t BSON_ALIGNED_END (8); /** * bson_iter_t: * * This structure manages iteration over a bson_t structure. It keeps track * of the location of the current key and value within the buffer. Using the * various functions to get the value of the iter will read from these * locations. * * This structure is safe to discard on the stack. No cleanup is necessary * after using it. */ BSON_ALIGNED_BEGIN (128) typedef struct { const uint8_t *raw; /* The raw buffer being iterated. */ uint32_t len; /* The length of raw. */ uint32_t off; /* The offset within the buffer. */ uint32_t type; /* The offset of the type byte. */ uint32_t key; /* The offset of the key byte. */ uint32_t d1; /* The offset of the first data byte. */ uint32_t d2; /* The offset of the second data byte. */ uint32_t d3; /* The offset of the third data byte. */ uint32_t d4; /* The offset of the fourth data byte. */ uint32_t next_off; /* The offset of the next field. */ uint32_t err_off; /* The offset of the error. */ bson_value_t value; /* Internal value for various state. */ } bson_iter_t BSON_ALIGNED_END (128); /** * bson_reader_t: * * This structure is used to iterate over a sequence of BSON documents. It * allows for them to be iterated with the possibility of no additional * memory allocations under certain circumstances such as reading from an * incoming mongo packet. */ BSON_ALIGNED_BEGIN (BSON_ALIGN_OF_PTR) typedef struct { uint32_t type; /*< private >*/ } bson_reader_t BSON_ALIGNED_END (BSON_ALIGN_OF_PTR); /** * bson_visitor_t: * * This structure contains a series of pointers that can be executed for * each field of a BSON document based on the field type. * * For example, if an int32 field is found, visit_int32 will be called. * * When visiting each field using bson_iter_visit_all(), you may provide a * data pointer that will be provided with each callback. This might be useful * if you are marshaling to another language. * * You may pre-maturely stop the visitation of fields by returning true in your * visitor. Returning false will continue visitation to further fields. */ BSON_ALIGNED_BEGIN (8) typedef struct { bool (*visit_before) (const bson_iter_t *iter, const char *key, void *data); bool (*visit_after) (const bson_iter_t *iter, const char *key, void *data); void (*visit_corrupt) (const bson_iter_t *iter, void *data); bool (*visit_double) (const bson_iter_t *iter, const char *key, double v_double, void *data); bool (*visit_utf8) (const bson_iter_t *iter, const char *key, size_t v_utf8_len, const char *v_utf8, void *data); bool (*visit_document) (const bson_iter_t *iter, const char *key, const bson_t *v_document, void *data); bool (*visit_array) (const bson_iter_t *iter, const char *key, const bson_t *v_array, void *data); bool (*visit_binary) (const bson_iter_t *iter, const char *key, bson_subtype_t v_subtype, size_t v_binary_len, const uint8_t *v_binary, void *data); bool (*visit_undefined) (const bson_iter_t *iter, const char *key, void *data); bool (*visit_oid) (const bson_iter_t *iter, const char *key, const bson_oid_t *v_oid, void *data); bool (*visit_bool) (const bson_iter_t *iter, const char *key, bool v_bool, void *data); bool (*visit_date_time) (const bson_iter_t *iter, const char *key, int64_t msec_since_epoch, void *data); bool (*visit_null) (const bson_iter_t *iter, const char *key, void *data); bool (*visit_regex) (const bson_iter_t *iter, const char *key, const char *v_regex, const char *v_options, void *data); bool (*visit_dbpointer) (const bson_iter_t *iter, const char *key, size_t v_collection_len, const char *v_collection, const bson_oid_t *v_oid, void *data); bool (*visit_code) (const bson_iter_t *iter, const char *key, size_t v_code_len, const char *v_code, void *data); bool (*visit_symbol) (const bson_iter_t *iter, const char *key, size_t v_symbol_len, const char *v_symbol, void *data); bool (*visit_codewscope) (const bson_iter_t *iter, const char *key, size_t v_code_len, const char *v_code, const bson_t *v_scope, void *data); bool (*visit_int32) (const bson_iter_t *iter, const char *key, int32_t v_int32, void *data); bool (*visit_timestamp) (const bson_iter_t *iter, const char *key, uint32_t v_timestamp, uint32_t v_increment, void *data); bool (*visit_int64) (const bson_iter_t *iter, const char *key, int64_t v_int64, void *data); bool (*visit_maxkey) (const bson_iter_t *iter, const char *key, void *data); bool (*visit_minkey) (const bson_iter_t *iter, const char *key, void *data); void *padding[9]; } bson_visitor_t BSON_ALIGNED_END (8); BSON_ALIGNED_BEGIN (8) typedef struct _bson_error_t { uint32_t domain; uint32_t code; char message[504]; } bson_error_t BSON_ALIGNED_END (8); BSON_STATIC_ASSERT (sizeof (bson_error_t) == 512); /** * bson_next_power_of_two: * @v: A 32-bit unsigned integer of required bytes. * * Determines the next larger power of two for the value of @v * in a constant number of operations. * * It is up to the caller to guarantee this will not overflow. * * Returns: The next power of 2 from @v. */ static BSON_INLINE size_t bson_next_power_of_two (size_t v) { v--; v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; #if BSON_WORD_SIZE == 64 v |= v >> 32; #endif v++; return v; } static BSON_INLINE bool bson_is_power_of_two (uint32_t v) { return ((v != 0) && ((v & (v - 1)) == 0)); } BSON_END_DECLS #endif /* BSON_TYPES_H */ mongodb-1.1.5/src/libbson/src/bson/bson-utf8.c0000664000175000017500000002745112673034026020757 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include "bson-memory.h" #include "bson-string.h" #include "bson-utf8.h" /* *-------------------------------------------------------------------------- * * _bson_utf8_get_sequence -- * * Determine the sequence length of the first UTF-8 character in * @utf8. The sequence length is stored in @seq_length and the mask * for the first character is stored in @first_mask. * * Returns: * None. * * Side effects: * @seq_length is set. * @first_mask is set. * *-------------------------------------------------------------------------- */ static BSON_INLINE void _bson_utf8_get_sequence (const char *utf8, /* IN */ uint8_t *seq_length, /* OUT */ uint8_t *first_mask) /* OUT */ { unsigned char c = *(const unsigned char *)utf8; uint8_t m; uint8_t n; /* * See the following[1] for a description of what the given multi-byte * sequences will be based on the bits set of the first byte. We also need * to mask the first byte based on that. All subsequent bytes are masked * against 0x3F. * * [1] http://www.joelonsoftware.com/articles/Unicode.html */ if ((c & 0x80) == 0) { n = 1; m = 0x7F; } else if ((c & 0xE0) == 0xC0) { n = 2; m = 0x1F; } else if ((c & 0xF0) == 0xE0) { n = 3; m = 0x0F; } else if ((c & 0xF8) == 0xF0) { n = 4; m = 0x07; } else if ((c & 0xFC) == 0xF8) { n = 5; m = 0x03; } else if ((c & 0xFE) == 0xFC) { n = 6; m = 0x01; } else { n = 0; m = 0; } *seq_length = n; *first_mask = m; } /* *-------------------------------------------------------------------------- * * bson_utf8_validate -- * * Validates that @utf8 is a valid UTF-8 string. * * If @allow_null is true, then \0 is allowed within @utf8_len bytes * of @utf8. Generally, this is bad practice since the main point of * UTF-8 strings is that they can be used with strlen() and friends. * However, some languages such as Python can send UTF-8 encoded * strings with NUL's in them. * * Parameters: * @utf8: A UTF-8 encoded string. * @utf8_len: The length of @utf8 in bytes. * @allow_null: If \0 is allowed within @utf8, exclusing trailing \0. * * Returns: * true if @utf8 is valid UTF-8. otherwise false. * * Side effects: * None. * *-------------------------------------------------------------------------- */ bool bson_utf8_validate (const char *utf8, /* IN */ size_t utf8_len, /* IN */ bool allow_null) /* IN */ { bson_unichar_t c; uint8_t first_mask; uint8_t seq_length; unsigned i; unsigned j; BSON_ASSERT (utf8); for (i = 0; i < utf8_len; i += seq_length) { _bson_utf8_get_sequence (&utf8[i], &seq_length, &first_mask); /* * Ensure we have a valid multi-byte sequence length. */ if (!seq_length) { return false; } /* * Ensure we have enough bytes left. */ if ((utf8_len - i) < seq_length) { return false; } /* * Also calculate the next char as a unichar so we can * check code ranges for non-shortest form. */ c = utf8 [i] & first_mask; /* * Check the high-bits for each additional sequence byte. */ for (j = i + 1; j < (i + seq_length); j++) { c = (c << 6) | (utf8 [j] & 0x3F); if ((utf8[j] & 0xC0) != 0x80) { return false; } } /* * Check for NULL bytes afterwards. * * Hint: if you want to optimize this function, starting here to do * this in the same pass as the data above would probably be a good * idea. You would add a branch into the inner loop, but save possibly * on cache-line bouncing on larger strings. Just a thought. */ if (!allow_null) { for (j = 0; j < seq_length; j++) { if (((i + j) > utf8_len) || !utf8[i + j]) { return false; } } } /* * Code point wont fit in utf-16, not allowed. */ if (c > 0x0010FFFF) { return false; } /* * Byte is in reserved range for UTF-16 high-marks * for surrogate pairs. */ if ((c & 0xFFFFF800) == 0xD800) { return false; } /* * Check non-shortest form unicode. */ switch (seq_length) { case 1: if (c <= 0x007F) { continue; } return false; case 2: if ((c >= 0x0080) && (c <= 0x07FF)) { continue; } else if (c == 0) { /* Two-byte representation for NULL. */ continue; } return false; case 3: if (((c >= 0x0800) && (c <= 0x0FFF)) || ((c >= 0x1000) && (c <= 0xFFFF))) { continue; } return false; case 4: if (((c >= 0x10000) && (c <= 0x3FFFF)) || ((c >= 0x40000) && (c <= 0xFFFFF)) || ((c >= 0x100000) && (c <= 0x10FFFF))) { continue; } return false; default: return false; } } return true; } /* *-------------------------------------------------------------------------- * * bson_utf8_escape_for_json -- * * Allocates a new string matching @utf8 except that special * characters in JSON will be escaped. The resulting string is also * UTF-8 encoded. * * Both " and \ characters will be escaped. Additionally, if a NUL * byte is found before @utf8_len bytes, it will be converted to the * two byte UTF-8 sequence. * * Parameters: * @utf8: A UTF-8 encoded string. * @utf8_len: The length of @utf8 in bytes or -1 if NUL terminated. * * Returns: * A newly allocated string that should be freed with bson_free(). * * Side effects: * None. * *-------------------------------------------------------------------------- */ char * bson_utf8_escape_for_json (const char *utf8, /* IN */ ssize_t utf8_len) /* IN */ { bson_unichar_t c; bson_string_t *str; bool length_provided = true; const char *end; BSON_ASSERT (utf8); str = bson_string_new (NULL); if (utf8_len < 0) { length_provided = false; utf8_len = strlen (utf8); } end = utf8 + utf8_len; while (utf8 < end) { c = bson_utf8_get_char (utf8); switch (c) { case '\\': case '"': case '/': bson_string_append_c (str, '\\'); bson_string_append_unichar (str, c); break; case '\b': bson_string_append (str, "\\b"); break; case '\f': bson_string_append (str, "\\f"); break; case '\n': bson_string_append (str, "\\n"); break; case '\r': bson_string_append (str, "\\r"); break; case '\t': bson_string_append (str, "\\t"); break; default: if (c < ' ') { bson_string_append_printf (str, "\\u%04u", (unsigned)c); } else { bson_string_append_unichar (str, c); } break; } if (c) { utf8 = bson_utf8_next_char (utf8); } else { if (length_provided && !*utf8) { /* we escaped nil as '\u0000', now advance past it */ utf8++; } else { /* invalid UTF-8 */ bson_string_free (str, true); return NULL; } } } return bson_string_free (str, false); } /* *-------------------------------------------------------------------------- * * bson_utf8_get_char -- * * Fetches the next UTF-8 character from the UTF-8 sequence. * * Parameters: * @utf8: A string containing validated UTF-8. * * Returns: * A 32-bit bson_unichar_t reprsenting the multi-byte sequence. * * Side effects: * None. * *-------------------------------------------------------------------------- */ bson_unichar_t bson_utf8_get_char (const char *utf8) /* IN */ { bson_unichar_t c; uint8_t mask; uint8_t num; int i; BSON_ASSERT (utf8); _bson_utf8_get_sequence (utf8, &num, &mask); c = (*utf8) & mask; for (i = 1; i < num; i++) { c = (c << 6) | (utf8[i] & 0x3F); } return c; } /* *-------------------------------------------------------------------------- * * bson_utf8_next_char -- * * Returns an incremented pointer to the beginning of the next * multi-byte sequence in @utf8. * * Parameters: * @utf8: A string containing validated UTF-8. * * Returns: * An incremented pointer in @utf8. * * Side effects: * None. * *-------------------------------------------------------------------------- */ const char * bson_utf8_next_char (const char *utf8) /* IN */ { uint8_t mask; uint8_t num; BSON_ASSERT (utf8); _bson_utf8_get_sequence (utf8, &num, &mask); return utf8 + num; } /* *-------------------------------------------------------------------------- * * bson_utf8_from_unichar -- * * Converts the unichar to a sequence of utf8 bytes and stores those * in @utf8. The number of bytes in the sequence are stored in @len. * * Parameters: * @unichar: A bson_unichar_t. * @utf8: A location for the multi-byte sequence. * @len: A location for number of bytes stored in @utf8. * * Returns: * None. * * Side effects: * @utf8 is set. * @len is set. * *-------------------------------------------------------------------------- */ void bson_utf8_from_unichar ( bson_unichar_t unichar, /* IN */ char utf8[BSON_ENSURE_ARRAY_PARAM_SIZE(6)], /* OUT */ uint32_t *len) /* OUT */ { BSON_ASSERT (utf8); BSON_ASSERT (len); if (unichar <= 0x7F) { utf8[0] = unichar; *len = 1; } else if (unichar <= 0x7FF) { *len = 2; utf8[0] = 0xC0 | ((unichar >> 6) & 0x3F); utf8[1] = 0x80 | ((unichar) & 0x3F); } else if (unichar <= 0xFFFF) { *len = 3; utf8[0] = 0xE0 | ((unichar >> 12) & 0xF); utf8[1] = 0x80 | ((unichar >> 6) & 0x3F); utf8[2] = 0x80 | ((unichar) & 0x3F); } else if (unichar <= 0x1FFFFF) { *len = 4; utf8[0] = 0xF0 | ((unichar >> 18) & 0x7); utf8[1] = 0x80 | ((unichar >> 12) & 0x3F); utf8[2] = 0x80 | ((unichar >> 6) & 0x3F); utf8[3] = 0x80 | ((unichar) & 0x3F); } else if (unichar <= 0x3FFFFFF) { *len = 5; utf8[0] = 0xF8 | ((unichar >> 24) & 0x3); utf8[1] = 0x80 | ((unichar >> 18) & 0x3F); utf8[2] = 0x80 | ((unichar >> 12) & 0x3F); utf8[3] = 0x80 | ((unichar >> 6) & 0x3F); utf8[4] = 0x80 | ((unichar) & 0x3F); } else if (unichar <= 0x7FFFFFFF) { *len = 6; utf8[0] = 0xFC | ((unichar >> 31) & 0x1); utf8[1] = 0x80 | ((unichar >> 25) & 0x3F); utf8[2] = 0x80 | ((unichar >> 19) & 0x3F); utf8[3] = 0x80 | ((unichar >> 13) & 0x3F); utf8[4] = 0x80 | ((unichar >> 7) & 0x3F); utf8[5] = 0x80 | ((unichar) & 0x1); } else { *len = 0; } } mongodb-1.1.5/src/libbson/src/bson/bson-utf8.h0000664000175000017500000000301012673034026020745 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef BSON_UTF8_H #define BSON_UTF8_H #if !defined (BSON_INSIDE) && !defined (BSON_COMPILATION) # error "Only can be included directly." #endif #include "bson-macros.h" #include "bson-types.h" BSON_BEGIN_DECLS bool bson_utf8_validate (const char *utf8, size_t utf8_len, bool allow_null); char *bson_utf8_escape_for_json (const char *utf8, ssize_t utf8_len); bson_unichar_t bson_utf8_get_char (const char *utf8); const char *bson_utf8_next_char (const char *utf8); void bson_utf8_from_unichar (bson_unichar_t unichar, char utf8[6], uint32_t *len); BSON_END_DECLS #endif /* BSON_UTF8_H */ mongodb-1.1.5/src/libbson/src/bson/bson-value.c0000664000175000017500000001425512673034026021203 0ustar jmikolajmikola/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "bson-memory.h" #include "bson-string.h" #include "bson-value.h" #include "bson-oid.h" void bson_value_copy (const bson_value_t *src, /* IN */ bson_value_t *dst) /* OUT */ { BSON_ASSERT (src); BSON_ASSERT (dst); dst->value_type = src->value_type; switch (src->value_type) { case BSON_TYPE_DOUBLE: dst->value.v_double = src->value.v_double; break; case BSON_TYPE_UTF8: dst->value.v_utf8.len = src->value.v_utf8.len; dst->value.v_utf8.str = bson_malloc (src->value.v_utf8.len + 1); memcpy (dst->value.v_utf8.str, src->value.v_utf8.str, dst->value.v_utf8.len); dst->value.v_utf8.str [dst->value.v_utf8.len] = '\0'; break; case BSON_TYPE_DOCUMENT: case BSON_TYPE_ARRAY: dst->value.v_doc.data_len = src->value.v_doc.data_len; dst->value.v_doc.data = bson_malloc (src->value.v_doc.data_len); memcpy (dst->value.v_doc.data, src->value.v_doc.data, dst->value.v_doc.data_len); break; case BSON_TYPE_BINARY: dst->value.v_binary.subtype = src->value.v_binary.subtype; dst->value.v_binary.data_len = src->value.v_binary.data_len; dst->value.v_binary.data = bson_malloc (src->value.v_binary.data_len); memcpy (dst->value.v_binary.data, src->value.v_binary.data, dst->value.v_binary.data_len); break; case BSON_TYPE_OID: bson_oid_copy (&src->value.v_oid, &dst->value.v_oid); break; case BSON_TYPE_BOOL: dst->value.v_bool = src->value.v_bool; break; case BSON_TYPE_DATE_TIME: dst->value.v_datetime = src->value.v_datetime; break; case BSON_TYPE_REGEX: dst->value.v_regex.regex = bson_strdup (src->value.v_regex.regex); dst->value.v_regex.options = bson_strdup (src->value.v_regex.options); break; case BSON_TYPE_DBPOINTER: dst->value.v_dbpointer.collection_len = src->value.v_dbpointer.collection_len; dst->value.v_dbpointer.collection = bson_malloc (src->value.v_dbpointer.collection_len + 1); memcpy (dst->value.v_dbpointer.collection, src->value.v_dbpointer.collection, dst->value.v_dbpointer.collection_len); dst->value.v_dbpointer.collection [dst->value.v_dbpointer.collection_len] = '\0'; bson_oid_copy (&src->value.v_dbpointer.oid, &dst->value.v_dbpointer.oid); break; case BSON_TYPE_CODE: dst->value.v_code.code_len = src->value.v_code.code_len; dst->value.v_code.code = bson_malloc (src->value.v_code.code_len + 1); memcpy (dst->value.v_code.code, src->value.v_code.code, dst->value.v_code.code_len); dst->value.v_code.code [dst->value.v_code.code_len] = '\0'; break; case BSON_TYPE_SYMBOL: dst->value.v_symbol.len = src->value.v_symbol.len; dst->value.v_symbol.symbol = bson_malloc (src->value.v_symbol.len + 1); memcpy (dst->value.v_symbol.symbol, src->value.v_symbol.symbol, dst->value.v_symbol.len); dst->value.v_symbol.symbol [dst->value.v_symbol.len] = '\0'; break; case BSON_TYPE_CODEWSCOPE: dst->value.v_codewscope.code_len = src->value.v_codewscope.code_len; dst->value.v_codewscope.code = bson_malloc (src->value.v_codewscope.code_len + 1); memcpy (dst->value.v_codewscope.code, src->value.v_codewscope.code, dst->value.v_codewscope.code_len); dst->value.v_codewscope.code [dst->value.v_codewscope.code_len] = '\0'; dst->value.v_codewscope.scope_len = src->value.v_codewscope.scope_len; dst->value.v_codewscope.scope_data = bson_malloc (src->value.v_codewscope.scope_len); memcpy (dst->value.v_codewscope.scope_data, src->value.v_codewscope.scope_data, dst->value.v_codewscope.scope_len); break; case BSON_TYPE_INT32: dst->value.v_int32 = src->value.v_int32; break; case BSON_TYPE_TIMESTAMP: dst->value.v_timestamp.timestamp = src->value.v_timestamp.timestamp; dst->value.v_timestamp.increment = src->value.v_timestamp.increment; break; case BSON_TYPE_INT64: dst->value.v_int64 = src->value.v_int64; break; case BSON_TYPE_UNDEFINED: case BSON_TYPE_NULL: case BSON_TYPE_MAXKEY: case BSON_TYPE_MINKEY: break; case BSON_TYPE_EOD: default: BSON_ASSERT (false); return; } } void bson_value_destroy (bson_value_t *value) /* IN */ { switch (value->value_type) { case BSON_TYPE_UTF8: bson_free (value->value.v_utf8.str); break; case BSON_TYPE_DOCUMENT: case BSON_TYPE_ARRAY: bson_free (value->value.v_doc.data); break; case BSON_TYPE_BINARY: bson_free (value->value.v_binary.data); break; case BSON_TYPE_REGEX: bson_free (value->value.v_regex.regex); bson_free (value->value.v_regex.options); break; case BSON_TYPE_DBPOINTER: bson_free (value->value.v_dbpointer.collection); break; case BSON_TYPE_CODE: bson_free (value->value.v_code.code); break; case BSON_TYPE_SYMBOL: bson_free (value->value.v_symbol.symbol); break; case BSON_TYPE_CODEWSCOPE: bson_free (value->value.v_codewscope.code); bson_free (value->value.v_codewscope.scope_data); break; case BSON_TYPE_DOUBLE: case BSON_TYPE_UNDEFINED: case BSON_TYPE_OID: case BSON_TYPE_BOOL: case BSON_TYPE_DATE_TIME: case BSON_TYPE_NULL: case BSON_TYPE_INT32: case BSON_TYPE_TIMESTAMP: case BSON_TYPE_INT64: case BSON_TYPE_MAXKEY: case BSON_TYPE_MINKEY: case BSON_TYPE_EOD: default: break; } } mongodb-1.1.5/src/libbson/src/bson/bson-value.h0000664000175000017500000000161612673034026021205 0ustar jmikolajmikola/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef BSON_VALUE_H #define BSON_VALUE_H #include "bson-macros.h" #include "bson-types.h" BSON_BEGIN_DECLS void bson_value_copy (const bson_value_t *src, bson_value_t *dst); void bson_value_destroy (bson_value_t *value); BSON_END_DECLS #endif /* BSON_VALUE_H */ mongodb-1.1.5/src/libbson/src/bson/bson-version-functions.c0000664000175000017500000000323512673034026023556 0ustar jmikolajmikola/* * Copyright 2015 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "bson-version.h" #include "bson-version-functions.h" /** * bson_get_major_version: * * Helper function to return the runtime major version of the library. */ int bson_get_major_version (void) { return BSON_MAJOR_VERSION; } /** * bson_get_minor_version: * * Helper function to return the runtime minor version of the library. */ int bson_get_minor_version (void) { return BSON_MINOR_VERSION; } /** * bson_get_micro_version: * * Helper function to return the runtime micro version of the library. */ int bson_get_micro_version (void) { return BSON_MICRO_VERSION; } /** * bson_get_version: * * Helper function to return the runtime string version of the library. */ const char * bson_get_version (void) { return BSON_VERSION_S; } /** * bson_check_version: * * True if libmongoc's version is greater than or equal to the required * version. */ bool bson_check_version (int required_major, int required_minor, int required_micro) { return BSON_CHECK_VERSION(required_major, required_minor, required_micro); } mongodb-1.1.5/src/libbson/src/bson/bson-version-functions.h0000664000175000017500000000214712673034026023564 0ustar jmikolajmikola/* * Copyright 2015 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if !defined (BSON_INSIDE) && !defined (BSON_COMPILATION) #error "Only can be included directly." #endif #ifndef BSON_VERSION_FUNCTIONS_H #define BSON_VERSION_FUNCTIONS_H #include "bson-types.h" int bson_get_major_version (void); int bson_get_minor_version (void); int bson_get_micro_version (void); const char *bson_get_version (void); bool bson_check_version (int required_major, int required_minor, int required_micro); #endif /* BSON_VERSION_FUNCTIONS_H */ mongodb-1.1.5/src/libbson/src/bson/bson-version.h0000664000175000017500000000452112673034026021554 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if !defined (BSON_INSIDE) && !defined (BSON_COMPILATION) #error "Only can be included directly." #endif #ifndef BSON_VERSION_H #define BSON_VERSION_H /** * BSON_MAJOR_VERSION: * * BSON major version component (e.g. 1 if %BSON_VERSION is 1.2.3) */ #define BSON_MAJOR_VERSION (1) /** * BSON_MINOR_VERSION: * * BSON minor version component (e.g. 2 if %BSON_VERSION is 1.2.3) */ #define BSON_MINOR_VERSION (3) /** * BSON_MICRO_VERSION: * * BSON micro version component (e.g. 3 if %BSON_VERSION is 1.2.3) */ #define BSON_MICRO_VERSION (3) /** * BSON_PRERELEASE_VERSION: * * BSON prerelease version component (e.g. rc0 if %BSON_VERSION is 1.2.3-rc0) */ #define BSON_PRERELEASE_VERSION () /** * BSON_VERSION: * * BSON version. */ #define BSON_VERSION (1.3.3) /** * BSON_VERSION_S: * * BSON version, encoded as a string, useful for printing and * concatenation. */ #define BSON_VERSION_S "1.3.3" /** * BSON_VERSION_HEX: * * BSON version, encoded as an hexadecimal number, useful for * integer comparisons. */ #define BSON_VERSION_HEX (BSON_MAJOR_VERSION << 24 | \ BSON_MINOR_VERSION << 16 | \ BSON_MICRO_VERSION << 8) /** * BSON_CHECK_VERSION: * @major: required major version * @minor: required minor version * @micro: required micro version * * Compile-time version checking. Evaluates to %TRUE if the version * of BSON is greater than the required one. */ #define BSON_CHECK_VERSION(major,minor,micro) \ (BSON_MAJOR_VERSION > (major) || \ (BSON_MAJOR_VERSION == (major) && BSON_MINOR_VERSION > (minor)) || \ (BSON_MAJOR_VERSION == (major) && BSON_MINOR_VERSION == (minor) && \ BSON_MICRO_VERSION >= (micro))) #endif /* BSON_VERSION_H */ mongodb-1.1.5/src/libbson/src/bson/bson-version.h.in0000664000175000017500000000466512673034026022172 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if !defined (BSON_INSIDE) && !defined (BSON_COMPILATION) #error "Only can be included directly." #endif #ifndef BSON_VERSION_H #define BSON_VERSION_H /** * BSON_MAJOR_VERSION: * * BSON major version component (e.g. 1 if %BSON_VERSION is 1.2.3) */ #define BSON_MAJOR_VERSION (@BSON_MAJOR_VERSION@) /** * BSON_MINOR_VERSION: * * BSON minor version component (e.g. 2 if %BSON_VERSION is 1.2.3) */ #define BSON_MINOR_VERSION (@BSON_MINOR_VERSION@) /** * BSON_MICRO_VERSION: * * BSON micro version component (e.g. 3 if %BSON_VERSION is 1.2.3) */ #define BSON_MICRO_VERSION (@BSON_MICRO_VERSION@) /** * BSON_PRERELEASE_VERSION: * * BSON prerelease version component (e.g. rc0 if %BSON_VERSION is 1.2.3-rc0) */ #define BSON_PRERELEASE_VERSION (@BSON_PRERELEASE_VERSION@) /** * BSON_VERSION: * * BSON version. */ #define BSON_VERSION (@BSON_VERSION@) /** * BSON_VERSION_S: * * BSON version, encoded as a string, useful for printing and * concatenation. */ #define BSON_VERSION_S "@BSON_VERSION@" /** * BSON_VERSION_HEX: * * BSON version, encoded as an hexadecimal number, useful for * integer comparisons. */ #define BSON_VERSION_HEX (BSON_MAJOR_VERSION << 24 | \ BSON_MINOR_VERSION << 16 | \ BSON_MICRO_VERSION << 8) /** * BSON_CHECK_VERSION: * @major: required major version * @minor: required minor version * @micro: required micro version * * Compile-time version checking. Evaluates to %TRUE if the version * of BSON is greater than the required one. */ #define BSON_CHECK_VERSION(major,minor,micro) \ (BSON_MAJOR_VERSION > (major) || \ (BSON_MAJOR_VERSION == (major) && BSON_MINOR_VERSION > (minor)) || \ (BSON_MAJOR_VERSION == (major) && BSON_MINOR_VERSION == (minor) && \ BSON_MICRO_VERSION >= (micro))) #endif /* BSON_VERSION_H */ mongodb-1.1.5/src/libbson/src/bson/bson-writer.c0000664000175000017500000001544212673034026021402 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "bson-private.h" #include "bson-writer.h" struct _bson_writer_t { bool ready; uint8_t **buf; size_t *buflen; size_t offset; bson_realloc_func realloc_func; void *realloc_func_ctx; bson_t b; }; /* *-------------------------------------------------------------------------- * * bson_writer_new -- * * Creates a new instance of bson_writer_t using the buffer, length, * offset, and realloc() function supplied. * * The caller is expected to clean up the structure when finished * using bson_writer_destroy(). * * Parameters: * @buf: (inout): A pointer to a target buffer. * @buflen: (inout): A pointer to the buffer length. * @offset: The offset in the target buffer to start from. * @realloc_func: A realloc() style function or NULL. * * Returns: * A newly allocated bson_writer_t that should be freed with * bson_writer_destroy(). * * Side effects: * None. * *-------------------------------------------------------------------------- */ bson_writer_t * bson_writer_new (uint8_t **buf, /* IN */ size_t *buflen, /* IN */ size_t offset, /* IN */ bson_realloc_func realloc_func, /* IN */ void *realloc_func_ctx) /* IN */ { bson_writer_t *writer; writer = bson_malloc0 (sizeof *writer); writer->buf = buf; writer->buflen = buflen; writer->offset = offset; writer->realloc_func = realloc_func; writer->realloc_func_ctx = realloc_func_ctx; writer->ready = true; return writer; } /* *-------------------------------------------------------------------------- * * bson_writer_destroy -- * * Cleanup after @writer and release any allocated memory. Note that * the buffer supplied to bson_writer_new() is NOT freed from this * method. The caller is responsible for that. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void bson_writer_destroy (bson_writer_t *writer) /* IN */ { bson_free (writer); } /* *-------------------------------------------------------------------------- * * bson_writer_get_length -- * * Fetches the current length of the content written by the buffer * (including the initial offset). This includes a partly written * document currently being written. * * This is useful if you want to check to see if you've passed a given * memory boundry that cannot be sent in a packet. See * bson_writer_rollback() to abort the current document being written. * * Returns: * The number of bytes written plus initial offset. * * Side effects: * None. * *-------------------------------------------------------------------------- */ size_t bson_writer_get_length (bson_writer_t *writer) /* IN */ { return writer->offset + writer->b.len; } /* *-------------------------------------------------------------------------- * * bson_writer_begin -- * * Begins writing a new document. The caller may use the bson * structure to write out a new BSON document. When completed, the * caller must call either bson_writer_end() or * bson_writer_rollback(). * * Parameters: * @writer: A bson_writer_t. * @bson: (out): A location for a bson_t*. * * Returns: * true if the underlying realloc was successful; otherwise false. * * Side effects: * @bson is initialized if true is returned. * *-------------------------------------------------------------------------- */ bool bson_writer_begin (bson_writer_t *writer, /* IN */ bson_t **bson) /* OUT */ { bson_impl_alloc_t *b; bool grown = false; BSON_ASSERT (writer); BSON_ASSERT (writer->ready); BSON_ASSERT (bson); writer->ready = false; memset (&writer->b, 0, sizeof (bson_t)); b = (bson_impl_alloc_t *)&writer->b; b->flags = BSON_FLAG_STATIC | BSON_FLAG_NO_FREE; b->len = 5; b->parent = NULL; b->buf = writer->buf; b->buflen = writer->buflen; b->offset = writer->offset; b->alloc = NULL; b->alloclen = 0; b->realloc = writer->realloc_func; b->realloc_func_ctx = writer->realloc_func_ctx; while ((writer->offset + writer->b.len) > *writer->buflen) { if (!writer->realloc_func) { memset (&writer->b, 0, sizeof (bson_t)); writer->ready = true; return false; } grown = true; if (!*writer->buflen) { *writer->buflen = 64; } else { (*writer->buflen) *= 2; } } if (grown) { *writer->buf = writer->realloc_func (*writer->buf, *writer->buflen, writer->realloc_func_ctx); } memset ((*writer->buf) + writer->offset + 1, 0, 5); (*writer->buf)[writer->offset] = 5; *bson = &writer->b; return true; } /* *-------------------------------------------------------------------------- * * bson_writer_end -- * * Complete writing of a bson_writer_t to the buffer supplied. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void bson_writer_end (bson_writer_t *writer) /* IN */ { BSON_ASSERT (writer); BSON_ASSERT (!writer->ready); writer->offset += writer->b.len; memset (&writer->b, 0, sizeof (bson_t)); writer->ready = true; } /* *-------------------------------------------------------------------------- * * bson_writer_rollback -- * * Abort the appending of the current bson_t to the memory region * managed by @writer. This is useful if you detected that you went * past a particular memory limit. For example, MongoDB has 48MB * message limits. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void bson_writer_rollback (bson_writer_t *writer) /* IN */ { BSON_ASSERT (writer); if (writer->b.len) { memset (&writer->b, 0, sizeof (bson_t)); } writer->ready = true; } mongodb-1.1.5/src/libbson/src/bson/bson-writer.h0000664000175000017500000000364012673034026021404 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef BSON_WRITER_H #define BSON_WRITER_H #include "bson.h" BSON_BEGIN_DECLS /** * bson_writer_t: * * The bson_writer_t structure is a helper for writing a series of BSON * documents to a single malloc() buffer. You can provide a realloc() style * function to grow the buffer as you go. * * This is useful if you want to build a series of BSON documents right into * the target buffer for an outgoing packet. The offset parameter allows you to * start at an offset of the target buffer. */ typedef struct _bson_writer_t bson_writer_t; bson_writer_t *bson_writer_new (uint8_t **buf, size_t *buflen, size_t offset, bson_realloc_func realloc_func, void *realloc_func_ctx); void bson_writer_destroy (bson_writer_t *writer); size_t bson_writer_get_length (bson_writer_t *writer); bool bson_writer_begin (bson_writer_t *writer, bson_t **bson); void bson_writer_end (bson_writer_t *writer); void bson_writer_rollback (bson_writer_t *writer); BSON_END_DECLS #endif /* BSON_WRITER_H */ mongodb-1.1.5/src/libbson/src/bson/bson.c0000664000175000017500000022670612673034026020077 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "bson.h" #include "b64_ntop.h" #include "bson-private.h" #include "bson-string.h" #include #include #include #ifndef BSON_MAX_RECURSION # define BSON_MAX_RECURSION 100 #endif typedef enum { BSON_VALIDATE_PHASE_START, BSON_VALIDATE_PHASE_TOP, BSON_VALIDATE_PHASE_LF_REF_KEY, BSON_VALIDATE_PHASE_LF_REF_UTF8, BSON_VALIDATE_PHASE_LF_ID_KEY, BSON_VALIDATE_PHASE_LF_DB_KEY, BSON_VALIDATE_PHASE_LF_DB_UTF8, BSON_VALIDATE_PHASE_NOT_DBREF, } bson_validate_phase_t; /* * Structures. */ typedef struct { bson_validate_flags_t flags; ssize_t err_offset; bson_validate_phase_t phase; } bson_validate_state_t; typedef struct { uint32_t count; bool keys; uint32_t depth; bson_string_t *str; } bson_json_state_t; /* * Forward declarations. */ static bool _bson_as_json_visit_array (const bson_iter_t *iter, const char *key, const bson_t *v_array, void *data); static bool _bson_as_json_visit_document (const bson_iter_t *iter, const char *key, const bson_t *v_document, void *data); /* * Globals. */ static const uint8_t gZero; /* *-------------------------------------------------------------------------- * * _bson_impl_inline_grow -- * * Document growth implementation for documents that currently * contain stack based buffers. The document may be switched to * a malloc based buffer. * * Returns: * true if successful; otherwise false indicating INT_MAX overflow. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static bool _bson_impl_inline_grow (bson_impl_inline_t *impl, /* IN */ size_t size) /* IN */ { bson_impl_alloc_t *alloc = (bson_impl_alloc_t *)impl; uint8_t *data; size_t req; if (((size_t)impl->len + size) <= sizeof impl->data) { return true; } req = bson_next_power_of_two (impl->len + size); if (req <= INT32_MAX) { data = bson_malloc (req); memcpy (data, impl->data, impl->len); alloc->flags &= ~BSON_FLAG_INLINE; alloc->parent = NULL; alloc->depth = 0; alloc->buf = &alloc->alloc; alloc->buflen = &alloc->alloclen; alloc->offset = 0; alloc->alloc = data; alloc->alloclen = req; alloc->realloc = bson_realloc_ctx; alloc->realloc_func_ctx = NULL; return true; } return false; } /* *-------------------------------------------------------------------------- * * _bson_impl_alloc_grow -- * * Document growth implementation for documents containing malloc * based buffers. * * Returns: * true if successful; otherwise false indicating INT_MAX overflow. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static bool _bson_impl_alloc_grow (bson_impl_alloc_t *impl, /* IN */ size_t size) /* IN */ { size_t req; /* * Determine how many bytes we need for this document in the buffer * including necessary trailing bytes for parent documents. */ req = (impl->offset + impl->len + size + impl->depth); if (req <= *impl->buflen) { return true; } req = bson_next_power_of_two (req); if ((req <= INT32_MAX) && impl->realloc) { *impl->buf = impl->realloc (*impl->buf, req, impl->realloc_func_ctx); *impl->buflen = req; return true; } return false; } /* *-------------------------------------------------------------------------- * * _bson_grow -- * * Grows the bson_t structure to be large enough to contain @size * bytes. * * Returns: * true if successful, false if the size would overflow. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static bool _bson_grow (bson_t *bson, /* IN */ uint32_t size) /* IN */ { if ((bson->flags & BSON_FLAG_INLINE)) { return _bson_impl_inline_grow ((bson_impl_inline_t *)bson, size); } return _bson_impl_alloc_grow ((bson_impl_alloc_t *)bson, size); } /* *-------------------------------------------------------------------------- * * _bson_data -- * * A helper function to return the contents of the bson document * taking into account the polymorphic nature of bson_t. * * Returns: * A buffer which should not be modified or freed. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static BSON_INLINE uint8_t * _bson_data (const bson_t *bson) /* IN */ { if ((bson->flags & BSON_FLAG_INLINE)) { return ((bson_impl_inline_t *)bson)->data; } else { bson_impl_alloc_t *impl = (bson_impl_alloc_t *)bson; return (*impl->buf) + impl->offset; } } /* *-------------------------------------------------------------------------- * * _bson_encode_length -- * * Helper to encode the length of the bson_t in the first 4 bytes * of the bson document. Little endian format is used as specified * by bsonspec. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static BSON_INLINE void _bson_encode_length (bson_t *bson) /* IN */ { #if BSON_BYTE_ORDER == BSON_LITTLE_ENDIAN memcpy (_bson_data (bson), &bson->len, sizeof (bson->len)); #else uint32_t length_le = BSON_UINT32_TO_LE (bson->len); memcpy (_bson_data (bson), &length_le, sizeof (length_le)); #endif } /* *-------------------------------------------------------------------------- * * _bson_append_va -- * * Appends the length,buffer pairs to the bson_t. @n_bytes is an * optimization to perform one array growth rather than many small * growths. * * @bson: A bson_t * @n_bytes: The number of bytes to append to the document. * @n_pairs: The number of length,buffer pairs. * @first_len: Length of first buffer. * @first_data: First buffer. * @args: va_list of additional tuples. * * Returns: * true if the bytes were appended successfully. * false if it bson would overflow INT_MAX. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static BSON_INLINE bool _bson_append_va (bson_t *bson, /* IN */ uint32_t n_bytes, /* IN */ uint32_t n_pairs, /* IN */ uint32_t first_len, /* IN */ const uint8_t *first_data, /* IN */ va_list args) /* IN */ { const uint8_t *data; uint32_t data_len; uint8_t *buf; BSON_ASSERT (!(bson->flags & BSON_FLAG_IN_CHILD)); BSON_ASSERT (!(bson->flags & BSON_FLAG_RDONLY)); if (BSON_UNLIKELY (!_bson_grow (bson, n_bytes))) { return false; } data = first_data; data_len = first_len; buf = _bson_data (bson) + bson->len - 1; do { n_pairs--; memcpy (buf, data, data_len); bson->len += data_len; buf += data_len; if (n_pairs) { data_len = va_arg (args, uint32_t); data = va_arg (args, const uint8_t *); } } while (n_pairs); _bson_encode_length (bson); *buf = '\0'; return true; } /* *-------------------------------------------------------------------------- * * _bson_append -- * * Variadic function to append length,buffer pairs to a bson_t. If the * append would cause the bson_t to overflow a 32-bit length, it will * return false and no append will have occurred. * * Parameters: * @bson: A bson_t. * @n_pairs: Number of length,buffer pairs. * @n_bytes: the total number of bytes being appended. * @first_len: Length of first buffer. * @first_data: First buffer. * * Returns: * true if successful; otherwise false indicating INT_MAX overflow. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static bool _bson_append (bson_t *bson, /* IN */ uint32_t n_pairs, /* IN */ uint32_t n_bytes, /* IN */ uint32_t first_len, /* IN */ const uint8_t *first_data, /* IN */ ...) { va_list args; bool ok; BSON_ASSERT (n_pairs); BSON_ASSERT (first_len); BSON_ASSERT (first_data); /* * Check to see if this append would overflow 32-bit signed integer. I know * what you're thinking. BSON uses a signed 32-bit length field? Yeah. It * does. */ if (BSON_UNLIKELY (n_bytes > (BSON_MAX_SIZE - bson->len))) { return false; } va_start (args, first_data); ok = _bson_append_va (bson, n_bytes, n_pairs, first_len, first_data, args); va_end (args); return ok; } /* *-------------------------------------------------------------------------- * * _bson_append_bson_begin -- * * Begin appending a subdocument or subarray to the document using * the key provided by @key. * * If @key_length is < 0, then strlen() will be called on @key * to determine the length. * * @key_type MUST be either BSON_TYPE_DOCUMENT or BSON_TYPE_ARRAY. * * Returns: * true if successful; otherwise false indicating INT_MAX overflow. * * Side effects: * @child is initialized if true is returned. * *-------------------------------------------------------------------------- */ static bool _bson_append_bson_begin (bson_t *bson, /* IN */ const char *key, /* IN */ int key_length, /* IN */ bson_type_t child_type, /* IN */ bson_t *child) /* OUT */ { const uint8_t type = child_type; const uint8_t empty[5] = { 5 }; bson_impl_alloc_t *aparent = (bson_impl_alloc_t *)bson; bson_impl_alloc_t *achild = (bson_impl_alloc_t *)child; BSON_ASSERT (!(bson->flags & BSON_FLAG_RDONLY)); BSON_ASSERT (!(bson->flags & BSON_FLAG_IN_CHILD)); BSON_ASSERT (key); BSON_ASSERT ((child_type == BSON_TYPE_DOCUMENT) || (child_type == BSON_TYPE_ARRAY)); BSON_ASSERT (child); if (key_length < 0) { key_length = (int)strlen (key); } /* * If the parent is an inline bson_t, then we need to convert * it to a heap allocated buffer. This makes extending buffers * of child bson documents much simpler logic, as they can just * realloc the *buf pointer. */ if ((bson->flags & BSON_FLAG_INLINE)) { BSON_ASSERT (bson->len <= 120); if (!_bson_grow (bson, 128 - bson->len)) { return false; } BSON_ASSERT (!(bson->flags & BSON_FLAG_INLINE)); } /* * Append the type and key for the field. */ if (!_bson_append (bson, 4, (1 + key_length + 1 + 5), 1, &type, key_length, key, 1, &gZero, 5, empty)) { return false; } /* * Mark the document as working on a child document so that no * further modifications can happen until the caller has called * bson_append_{document,array}_end(). */ bson->flags |= BSON_FLAG_IN_CHILD; /* * Initialize the child bson_t structure and point it at the parents * buffers. This allows us to realloc directly from the child without * walking up to the parent bson_t. */ achild->flags = (BSON_FLAG_CHILD | BSON_FLAG_NO_FREE | BSON_FLAG_STATIC); if ((bson->flags & BSON_FLAG_CHILD)) { achild->depth = ((bson_impl_alloc_t *)bson)->depth + 1; } else { achild->depth = 1; } achild->parent = bson; achild->buf = aparent->buf; achild->buflen = aparent->buflen; achild->offset = aparent->offset + aparent->len - 1 - 5; achild->len = 5; achild->alloc = NULL; achild->alloclen = 0; achild->realloc = aparent->realloc; achild->realloc_func_ctx = aparent->realloc_func_ctx; return true; } /* *-------------------------------------------------------------------------- * * _bson_append_bson_end -- * * Complete a call to _bson_append_bson_begin. * * Returns: * true if successful; otherwise false indicating INT_MAX overflow. * * Side effects: * @child is destroyed and no longer valid after calling this * function. * *-------------------------------------------------------------------------- */ static bool _bson_append_bson_end (bson_t *bson, /* IN */ bson_t *child) /* IN */ { BSON_ASSERT (bson); BSON_ASSERT ((bson->flags & BSON_FLAG_IN_CHILD)); BSON_ASSERT (!(child->flags & BSON_FLAG_IN_CHILD)); /* * Unmark the IN_CHILD flag. */ bson->flags &= ~BSON_FLAG_IN_CHILD; /* * Now that we are done building the sub-document, add the size to the * parent, not including the default 5 byte empty document already added. */ bson->len = (bson->len + child->len - 5); /* * Ensure we have a \0 byte at the end and proper length encoded at * the beginning of the document. */ _bson_data (bson)[bson->len - 1] = '\0'; _bson_encode_length (bson); return true; } /* *-------------------------------------------------------------------------- * * bson_append_array_begin -- * * Start appending a new array. * * Use @child to append to the data area for the given field. * * It is a programming error to call any other bson function on * @bson until bson_append_array_end() has been called. It is * valid to call bson_append*() functions on @child. * * This function is useful to allow building nested documents using * a single buffer owned by the top-level bson document. * * Returns: * true if successful; otherwise false and @child is invalid. * * Side effects: * @child is initialized if true is returned. * *-------------------------------------------------------------------------- */ bool bson_append_array_begin (bson_t *bson, /* IN */ const char *key, /* IN */ int key_length, /* IN */ bson_t *child) /* IN */ { BSON_ASSERT (bson); BSON_ASSERT (key); BSON_ASSERT (child); return _bson_append_bson_begin (bson, key, key_length, BSON_TYPE_ARRAY, child); } /* *-------------------------------------------------------------------------- * * bson_append_array_end -- * * Complete a call to bson_append_array_begin(). * * It is safe to append other fields to @bson after calling this * function. * * Returns: * true if successful; otherwise false indicating INT_MAX overflow. * * Side effects: * @child is invalid after calling this function. * *-------------------------------------------------------------------------- */ bool bson_append_array_end (bson_t *bson, /* IN */ bson_t *child) /* IN */ { BSON_ASSERT (bson); BSON_ASSERT (child); return _bson_append_bson_end (bson, child); } /* *-------------------------------------------------------------------------- * * bson_append_document_begin -- * * Start appending a new document. * * Use @child to append to the data area for the given field. * * It is a programming error to call any other bson function on * @bson until bson_append_document_end() has been called. It is * valid to call bson_append*() functions on @child. * * This function is useful to allow building nested documents using * a single buffer owned by the top-level bson document. * * Returns: * true if successful; otherwise false and @child is invalid. * * Side effects: * @child is initialized if true is returned. * *-------------------------------------------------------------------------- */ bool bson_append_document_begin (bson_t *bson, /* IN */ const char *key, /* IN */ int key_length, /* IN */ bson_t *child) /* IN */ { BSON_ASSERT (bson); BSON_ASSERT (key); BSON_ASSERT (child); return _bson_append_bson_begin (bson, key, key_length, BSON_TYPE_DOCUMENT, child); } /* *-------------------------------------------------------------------------- * * bson_append_document_end -- * * Complete a call to bson_append_document_begin(). * * It is safe to append new fields to @bson after calling this * function, if true is returned. * * Returns: * true if successful; otherwise false indicating INT_MAX overflow. * * Side effects: * @child is destroyed and invalid after calling this function. * *-------------------------------------------------------------------------- */ bool bson_append_document_end (bson_t *bson, /* IN */ bson_t *child) /* IN */ { BSON_ASSERT (bson); BSON_ASSERT (child); return _bson_append_bson_end (bson, child); } /* *-------------------------------------------------------------------------- * * bson_append_array -- * * Append an array to @bson. * * Generally, bson_append_array_begin() will result in faster code * since few buffers need to be malloced. * * Returns: * true if successful; otherwise false indicating INT_MAX overflow. * * Side effects: * None. * *-------------------------------------------------------------------------- */ bool bson_append_array (bson_t *bson, /* IN */ const char *key, /* IN */ int key_length, /* IN */ const bson_t *array) /* IN */ { static const uint8_t type = BSON_TYPE_ARRAY; BSON_ASSERT (bson); BSON_ASSERT (key); BSON_ASSERT (array); if (key_length < 0) { key_length = (int)strlen (key); } /* * Let's be a bit pedantic and ensure the array has properly formatted key * names. We will verify this simply by checking the first element for "0" * if the array is non-empty. */ if (array && !bson_empty (array)) { bson_iter_t iter; if (bson_iter_init (&iter, array) && bson_iter_next (&iter)) { if (0 != strcmp ("0", bson_iter_key (&iter))) { fprintf (stderr, "%s(): invalid array detected. first element of array " "parameter is not \"0\".\n", BSON_FUNC); } } } return _bson_append (bson, 4, (1 + key_length + 1 + array->len), 1, &type, key_length, key, 1, &gZero, array->len, _bson_data (array)); } /* *-------------------------------------------------------------------------- * * bson_append_binary -- * * Append binary data to @bson. The field will have the * BSON_TYPE_BINARY type. * * Parameters: * @subtype: the BSON Binary Subtype. See bsonspec.org for more * information. * @binary: a pointer to the raw binary data. * @length: the size of @binary in bytes. * * Returns: * true if successful; otherwise false. * * Side effects: * None. * *-------------------------------------------------------------------------- */ bool bson_append_binary (bson_t *bson, /* IN */ const char *key, /* IN */ int key_length, /* IN */ bson_subtype_t subtype, /* IN */ const uint8_t *binary, /* IN */ uint32_t length) /* IN */ { static const uint8_t type = BSON_TYPE_BINARY; uint32_t length_le; uint32_t deprecated_length_le; uint8_t subtype8 = 0; BSON_ASSERT (bson); BSON_ASSERT (key); BSON_ASSERT (binary); if (key_length < 0) { key_length = (int)strlen (key); } subtype8 = subtype; if (subtype == BSON_SUBTYPE_BINARY_DEPRECATED) { length_le = BSON_UINT32_TO_LE (length + 4); deprecated_length_le = BSON_UINT32_TO_LE (length); return _bson_append (bson, 7, (1 + key_length + 1 + 4 + 1 + 4 + length), 1, &type, key_length, key, 1, &gZero, 4, &length_le, 1, &subtype8, 4, &deprecated_length_le, length, binary); } else { length_le = BSON_UINT32_TO_LE (length); return _bson_append (bson, 6, (1 + key_length + 1 + 4 + 1 + length), 1, &type, key_length, key, 1, &gZero, 4, &length_le, 1, &subtype8, length, binary); } } /* *-------------------------------------------------------------------------- * * bson_append_bool -- * * Append a new field to @bson with the name @key. The value is * a boolean indicated by @value. * * Returns: * true if succesful; otherwise false. * * Side effects: * None. * *-------------------------------------------------------------------------- */ bool bson_append_bool (bson_t *bson, /* IN */ const char *key, /* IN */ int key_length, /* IN */ bool value) /* IN */ { static const uint8_t type = BSON_TYPE_BOOL; uint8_t abyte = !!value; BSON_ASSERT (bson); BSON_ASSERT (key); if (key_length < 0) { key_length = (int)strlen (key); } return _bson_append (bson, 4, (1 + key_length + 1 + 1), 1, &type, key_length, key, 1, &gZero, 1, &abyte); } /* *-------------------------------------------------------------------------- * * bson_append_code -- * * Append a new field to @bson containing javascript code. * * @javascript MUST be a zero terminated UTF-8 string. It MUST NOT * containing embedded \0 characters. * * Returns: * true if successful; otherwise false. * * Side effects: * None. * * See also: * bson_append_code_with_scope(). * *-------------------------------------------------------------------------- */ bool bson_append_code (bson_t *bson, /* IN */ const char *key, /* IN */ int key_length, /* IN */ const char *javascript) /* IN */ { static const uint8_t type = BSON_TYPE_CODE; uint32_t length; uint32_t length_le; BSON_ASSERT (bson); BSON_ASSERT (key); BSON_ASSERT (javascript); if (key_length < 0) { key_length = (int)strlen (key); } length = (int)strlen (javascript) + 1; length_le = BSON_UINT32_TO_LE (length); return _bson_append (bson, 5, (1 + key_length + 1 + 4 + length), 1, &type, key_length, key, 1, &gZero, 4, &length_le, length, javascript); } /* *-------------------------------------------------------------------------- * * bson_append_code_with_scope -- * * Append a new field to @bson containing javascript code with * supplied scope. * * Returns: * true if successful; otherwise false. * * Side effects: * None. * *-------------------------------------------------------------------------- */ bool bson_append_code_with_scope (bson_t *bson, /* IN */ const char *key, /* IN */ int key_length, /* IN */ const char *javascript, /* IN */ const bson_t *scope) /* IN */ { static const uint8_t type = BSON_TYPE_CODEWSCOPE; uint32_t codews_length_le; uint32_t codews_length; uint32_t js_length_le; uint32_t js_length; BSON_ASSERT (bson); BSON_ASSERT (key); BSON_ASSERT (javascript); if (bson_empty0 (scope)) { return bson_append_code (bson, key, key_length, javascript); } if (key_length < 0) { key_length = (int)strlen (key); } js_length = (int)strlen (javascript) + 1; js_length_le = BSON_UINT32_TO_LE (js_length); codews_length = 4 + 4 + js_length + scope->len; codews_length_le = BSON_UINT32_TO_LE (codews_length); return _bson_append (bson, 7, (1 + key_length + 1 + 4 + 4 + js_length + scope->len), 1, &type, key_length, key, 1, &gZero, 4, &codews_length_le, 4, &js_length_le, js_length, javascript, scope->len, _bson_data (scope)); } /* *-------------------------------------------------------------------------- * * bson_append_dbpointer -- * * This BSON data type is DEPRECATED. * * Append a BSON dbpointer field to @bson. * * Returns: * true if successful; otherwise false. * * Side effects: * None. * *-------------------------------------------------------------------------- */ bool bson_append_dbpointer (bson_t *bson, /* IN */ const char *key, /* IN */ int key_length, /* IN */ const char *collection, /* IN */ const bson_oid_t *oid) { static const uint8_t type = BSON_TYPE_DBPOINTER; uint32_t length; uint32_t length_le; BSON_ASSERT (bson); BSON_ASSERT (key); BSON_ASSERT (collection); BSON_ASSERT (oid); if (key_length < 0) { key_length = (int)strlen (key); } length = (int)strlen (collection) + 1; length_le = BSON_UINT32_TO_LE (length); return _bson_append (bson, 6, (1 + key_length + 1 + 4 + length + 12), 1, &type, key_length, key, 1, &gZero, 4, &length_le, length, collection, 12, oid); } /* *-------------------------------------------------------------------------- * * bson_append_document -- * * Append a new field to @bson containing a BSON document. * * In general, using bson_append_document_begin() results in faster * code and less memory fragmentation. * * Returns: * true if successful; otherwise false. * * Side effects: * None. * * See also: * bson_append_document_begin(). * *-------------------------------------------------------------------------- */ bool bson_append_document (bson_t *bson, /* IN */ const char *key, /* IN */ int key_length, /* IN */ const bson_t *value) /* IN */ { static const uint8_t type = BSON_TYPE_DOCUMENT; BSON_ASSERT (bson); BSON_ASSERT (key); BSON_ASSERT (value); if (key_length < 0) { key_length = (int)strlen (key); } return _bson_append (bson, 4, (1 + key_length + 1 + value->len), 1, &type, key_length, key, 1, &gZero, value->len, _bson_data (value)); } bool bson_append_double (bson_t *bson, const char *key, int key_length, double value) { static const uint8_t type = BSON_TYPE_DOUBLE; BSON_ASSERT (bson); BSON_ASSERT (key); if (key_length < 0) { key_length = (int)strlen (key); } #if BSON_BYTE_ORDER == BSON_BIG_ENDIAN value = BSON_DOUBLE_TO_LE (value); #endif return _bson_append (bson, 4, (1 + key_length + 1 + 8), 1, &type, key_length, key, 1, &gZero, 8, &value); } bool bson_append_int32 (bson_t *bson, const char *key, int key_length, int32_t value) { static const uint8_t type = BSON_TYPE_INT32; uint32_t value_le; BSON_ASSERT (bson); BSON_ASSERT (key); if (key_length < 0) { key_length = (int)strlen (key); } value_le = BSON_UINT32_TO_LE (value); return _bson_append (bson, 4, (1 + key_length + 1 + 4), 1, &type, key_length, key, 1, &gZero, 4, &value_le); } bool bson_append_int64 (bson_t *bson, const char *key, int key_length, int64_t value) { static const uint8_t type = BSON_TYPE_INT64; uint64_t value_le; BSON_ASSERT (bson); BSON_ASSERT (key); if (key_length < 0) { key_length = (int)strlen (key); } value_le = BSON_UINT64_TO_LE (value); return _bson_append (bson, 4, (1 + key_length + 1 + 8), 1, &type, key_length, key, 1, &gZero, 8, &value_le); } bool bson_append_iter (bson_t *bson, const char *key, int key_length, const bson_iter_t *iter) { bool ret = false; BSON_ASSERT (bson); BSON_ASSERT (iter); if (!key) { key = bson_iter_key (iter); key_length = -1; } switch (bson_iter_type_unsafe (iter)) { case BSON_TYPE_EOD: return false; case BSON_TYPE_DOUBLE: ret = bson_append_double (bson, key, key_length, bson_iter_double (iter)); break; case BSON_TYPE_UTF8: { uint32_t len = 0; const char *str; str = bson_iter_utf8 (iter, &len); ret = bson_append_utf8 (bson, key, key_length, str, len); } break; case BSON_TYPE_DOCUMENT: { const uint8_t *buf = NULL; uint32_t len = 0; bson_t doc; bson_iter_document (iter, &len, &buf); if (bson_init_static (&doc, buf, len)) { ret = bson_append_document (bson, key, key_length, &doc); bson_destroy (&doc); } } break; case BSON_TYPE_ARRAY: { const uint8_t *buf = NULL; uint32_t len = 0; bson_t doc; bson_iter_array (iter, &len, &buf); if (bson_init_static (&doc, buf, len)) { ret = bson_append_array (bson, key, key_length, &doc); bson_destroy (&doc); } } break; case BSON_TYPE_BINARY: { const uint8_t *binary = NULL; bson_subtype_t subtype = BSON_SUBTYPE_BINARY; uint32_t len = 0; bson_iter_binary (iter, &subtype, &len, &binary); ret = bson_append_binary (bson, key, key_length, subtype, binary, len); } break; case BSON_TYPE_UNDEFINED: ret = bson_append_undefined (bson, key, key_length); break; case BSON_TYPE_OID: ret = bson_append_oid (bson, key, key_length, bson_iter_oid (iter)); break; case BSON_TYPE_BOOL: ret = bson_append_bool (bson, key, key_length, bson_iter_bool (iter)); break; case BSON_TYPE_DATE_TIME: ret = bson_append_date_time (bson, key, key_length, bson_iter_date_time (iter)); break; case BSON_TYPE_NULL: ret = bson_append_null (bson, key, key_length); break; case BSON_TYPE_REGEX: { const char *regex; const char *options; regex = bson_iter_regex (iter, &options); ret = bson_append_regex (bson, key, key_length, regex, options); } break; case BSON_TYPE_DBPOINTER: { const bson_oid_t *oid; uint32_t len; const char *collection; bson_iter_dbpointer (iter, &len, &collection, &oid); ret = bson_append_dbpointer (bson, key, key_length, collection, oid); } break; case BSON_TYPE_CODE: { uint32_t len; const char *code; code = bson_iter_code (iter, &len); ret = bson_append_code (bson, key, key_length, code); } break; case BSON_TYPE_SYMBOL: { uint32_t len; const char *symbol; symbol = bson_iter_symbol (iter, &len); ret = bson_append_symbol (bson, key, key_length, symbol, len); } break; case BSON_TYPE_CODEWSCOPE: { const uint8_t *scope = NULL; uint32_t scope_len = 0; uint32_t len = 0; const char *javascript = NULL; bson_t doc; javascript = bson_iter_codewscope (iter, &len, &scope_len, &scope); if (bson_init_static (&doc, scope, scope_len)) { ret = bson_append_code_with_scope (bson, key, key_length, javascript, &doc); bson_destroy (&doc); } } break; case BSON_TYPE_INT32: ret = bson_append_int32 (bson, key, key_length, bson_iter_int32 (iter)); break; case BSON_TYPE_TIMESTAMP: { uint32_t ts; uint32_t inc; bson_iter_timestamp (iter, &ts, &inc); ret = bson_append_timestamp (bson, key, key_length, ts, inc); } break; case BSON_TYPE_INT64: ret = bson_append_int64 (bson, key, key_length, bson_iter_int64 (iter)); break; case BSON_TYPE_MAXKEY: ret = bson_append_maxkey (bson, key, key_length); break; case BSON_TYPE_MINKEY: ret = bson_append_minkey (bson, key, key_length); break; default: break; } return ret; } bool bson_append_maxkey (bson_t *bson, const char *key, int key_length) { static const uint8_t type = BSON_TYPE_MAXKEY; BSON_ASSERT (bson); BSON_ASSERT (key); if (key_length < 0) { key_length = (int)strlen (key); } return _bson_append (bson, 3, (1 + key_length + 1), 1, &type, key_length, key, 1, &gZero); } bool bson_append_minkey (bson_t *bson, const char *key, int key_length) { static const uint8_t type = BSON_TYPE_MINKEY; BSON_ASSERT (bson); BSON_ASSERT (key); if (key_length < 0) { key_length = (int)strlen (key); } return _bson_append (bson, 3, (1 + key_length + 1), 1, &type, key_length, key, 1, &gZero); } bool bson_append_null (bson_t *bson, const char *key, int key_length) { static const uint8_t type = BSON_TYPE_NULL; BSON_ASSERT (bson); BSON_ASSERT (key); if (key_length < 0) { key_length = (int)strlen (key); } return _bson_append (bson, 3, (1 + key_length + 1), 1, &type, key_length, key, 1, &gZero); } bool bson_append_oid (bson_t *bson, const char *key, int key_length, const bson_oid_t *value) { static const uint8_t type = BSON_TYPE_OID; BSON_ASSERT (bson); BSON_ASSERT (key); BSON_ASSERT (value); if (key_length < 0) { key_length = (int)strlen (key); } return _bson_append (bson, 4, (1 + key_length + 1 + 12), 1, &type, key_length, key, 1, &gZero, 12, value); } bool bson_append_regex (bson_t *bson, const char *key, int key_length, const char *regex, const char *options) { static const uint8_t type = BSON_TYPE_REGEX; uint32_t regex_len; uint32_t options_len; BSON_ASSERT (bson); BSON_ASSERT (key); if (key_length < 0) { key_length = (int)strlen (key); } if (!regex) { regex = ""; } if (!options) { options = ""; } regex_len = (int)strlen (regex) + 1; options_len = (int)strlen (options) + 1; return _bson_append (bson, 5, (1 + key_length + 1 + regex_len + options_len), 1, &type, key_length, key, 1, &gZero, regex_len, regex, options_len, options); } bool bson_append_utf8 (bson_t *bson, const char *key, int key_length, const char *value, int length) { static const uint8_t type = BSON_TYPE_UTF8; uint32_t length_le; BSON_ASSERT (bson); BSON_ASSERT (key); if (BSON_UNLIKELY (!value)) { return bson_append_null (bson, key, key_length); } if (BSON_UNLIKELY (key_length < 0)) { key_length = (int)strlen (key); } if (BSON_UNLIKELY (length < 0)) { length = (int)strlen (value); } length_le = BSON_UINT32_TO_LE (length + 1); return _bson_append (bson, 6, (1 + key_length + 1 + 4 + length + 1), 1, &type, key_length, key, 1, &gZero, 4, &length_le, length, value, 1, &gZero); } bool bson_append_symbol (bson_t *bson, const char *key, int key_length, const char *value, int length) { static const uint8_t type = BSON_TYPE_SYMBOL; uint32_t length_le; BSON_ASSERT (bson); BSON_ASSERT (key); if (!value) { return bson_append_null (bson, key, key_length); } if (key_length < 0) { key_length = (int)strlen (key); } if (length < 0) { length =(int)strlen (value); } length_le = BSON_UINT32_TO_LE (length + 1); return _bson_append (bson, 6, (1 + key_length + 1 + 4 + length + 1), 1, &type, key_length, key, 1, &gZero, 4, &length_le, length, value, 1, &gZero); } bool bson_append_time_t (bson_t *bson, const char *key, int key_length, time_t value) { #ifdef BSON_OS_WIN32 struct timeval tv = { (long)value, 0 }; #else struct timeval tv = { value, 0 }; #endif BSON_ASSERT (bson); BSON_ASSERT (key); return bson_append_timeval (bson, key, key_length, &tv); } bool bson_append_timestamp (bson_t *bson, const char *key, int key_length, uint32_t timestamp, uint32_t increment) { static const uint8_t type = BSON_TYPE_TIMESTAMP; uint64_t value; BSON_ASSERT (bson); BSON_ASSERT (key); if (key_length < 0) { key_length =(int)strlen (key); } value = ((((uint64_t)timestamp) << 32) | ((uint64_t)increment)); value = BSON_UINT64_TO_LE (value); return _bson_append (bson, 4, (1 + key_length + 1 + 8), 1, &type, key_length, key, 1, &gZero, 8, &value); } bool bson_append_now_utc (bson_t *bson, const char *key, int key_length) { BSON_ASSERT (bson); BSON_ASSERT (key); BSON_ASSERT (key_length >= -1); return bson_append_time_t (bson, key, key_length, time (NULL)); } bool bson_append_date_time (bson_t *bson, const char *key, int key_length, int64_t value) { static const uint8_t type = BSON_TYPE_DATE_TIME; uint64_t value_le; BSON_ASSERT (bson); BSON_ASSERT (key); if (key_length < 0) { key_length =(int)strlen (key); } value_le = BSON_UINT64_TO_LE (value); return _bson_append (bson, 4, (1 + key_length + 1 + 8), 1, &type, key_length, key, 1, &gZero, 8, &value_le); } bool bson_append_timeval (bson_t *bson, const char *key, int key_length, struct timeval *value) { uint64_t unix_msec; BSON_ASSERT (bson); BSON_ASSERT (key); BSON_ASSERT (value); unix_msec = (((uint64_t)value->tv_sec) * 1000UL) + (value->tv_usec / 1000UL); return bson_append_date_time (bson, key, key_length, unix_msec); } bool bson_append_undefined (bson_t *bson, const char *key, int key_length) { static const uint8_t type = BSON_TYPE_UNDEFINED; BSON_ASSERT (bson); BSON_ASSERT (key); if (key_length < 0) { key_length =(int)strlen (key); } return _bson_append (bson, 3, (1 + key_length + 1), 1, &type, key_length, key, 1, &gZero); } bool bson_append_value (bson_t *bson, const char *key, int key_length, const bson_value_t *value) { bson_t local; bool ret = false; BSON_ASSERT (bson); BSON_ASSERT (key); BSON_ASSERT (value); switch (value->value_type) { case BSON_TYPE_DOUBLE: ret = bson_append_double (bson, key, key_length, value->value.v_double); break; case BSON_TYPE_UTF8: ret = bson_append_utf8 (bson, key, key_length, value->value.v_utf8.str, value->value.v_utf8.len); break; case BSON_TYPE_DOCUMENT: if (bson_init_static (&local, value->value.v_doc.data, value->value.v_doc.data_len)) { ret = bson_append_document (bson, key, key_length, &local); bson_destroy (&local); } break; case BSON_TYPE_ARRAY: if (bson_init_static (&local, value->value.v_doc.data, value->value.v_doc.data_len)) { ret = bson_append_array (bson, key, key_length, &local); bson_destroy (&local); } break; case BSON_TYPE_BINARY: ret = bson_append_binary (bson, key, key_length, value->value.v_binary.subtype, value->value.v_binary.data, value->value.v_binary.data_len); break; case BSON_TYPE_UNDEFINED: ret = bson_append_undefined (bson, key, key_length); break; case BSON_TYPE_OID: ret = bson_append_oid (bson, key, key_length, &value->value.v_oid); break; case BSON_TYPE_BOOL: ret = bson_append_bool (bson, key, key_length, value->value.v_bool); break; case BSON_TYPE_DATE_TIME: ret = bson_append_date_time (bson, key, key_length, value->value.v_datetime); break; case BSON_TYPE_NULL: ret = bson_append_null (bson, key, key_length); break; case BSON_TYPE_REGEX: ret = bson_append_regex (bson, key, key_length, value->value.v_regex.regex, value->value.v_regex.options); break; case BSON_TYPE_DBPOINTER: ret = bson_append_dbpointer (bson, key, key_length, value->value.v_dbpointer.collection, &value->value.v_dbpointer.oid); break; case BSON_TYPE_CODE: ret = bson_append_code (bson, key, key_length, value->value.v_code.code); break; case BSON_TYPE_SYMBOL: ret = bson_append_symbol (bson, key, key_length, value->value.v_symbol.symbol, value->value.v_symbol.len); break; case BSON_TYPE_CODEWSCOPE: if (bson_init_static (&local, value->value.v_codewscope.scope_data, value->value.v_codewscope.scope_len)) { ret = bson_append_code_with_scope (bson, key, key_length, value->value.v_codewscope.code, &local); bson_destroy (&local); } break; case BSON_TYPE_INT32: ret = bson_append_int32 (bson, key, key_length, value->value.v_int32); break; case BSON_TYPE_TIMESTAMP: ret = bson_append_timestamp (bson, key, key_length, value->value.v_timestamp.timestamp, value->value.v_timestamp.increment); break; case BSON_TYPE_INT64: ret = bson_append_int64 (bson, key, key_length, value->value.v_int64); break; case BSON_TYPE_MAXKEY: ret = bson_append_maxkey (bson, key, key_length); break; case BSON_TYPE_MINKEY: ret = bson_append_minkey (bson, key, key_length); break; case BSON_TYPE_EOD: default: break; } return ret; } void bson_init (bson_t *bson) { bson_impl_inline_t *impl = (bson_impl_inline_t *)bson; BSON_ASSERT (bson); impl->flags = BSON_FLAG_INLINE | BSON_FLAG_STATIC; impl->len = 5; impl->data[0] = 5; impl->data[1] = 0; impl->data[2] = 0; impl->data[3] = 0; impl->data[4] = 0; } void bson_reinit (bson_t *bson) { uint8_t *data; BSON_ASSERT (bson); data = _bson_data (bson); bson->len = 5; data [0] = 5; data [1] = 0; data [2] = 0; data [3] = 0; data [4] = 0; } bool bson_init_static (bson_t *bson, const uint8_t *data, size_t length) { bson_impl_alloc_t *impl = (bson_impl_alloc_t *)bson; uint32_t len_le; BSON_ASSERT (bson); BSON_ASSERT (data); if ((length < 5) || (length > INT_MAX)) { return false; } memcpy (&len_le, data, sizeof (len_le)); if ((size_t)BSON_UINT32_FROM_LE (len_le) != length) { return false; } if (data[length - 1]) { return false; } impl->flags = BSON_FLAG_STATIC | BSON_FLAG_RDONLY; impl->len = (uint32_t)length; impl->parent = NULL; impl->depth = 0; impl->buf = &impl->alloc; impl->buflen = &impl->alloclen; impl->offset = 0; impl->alloc = (uint8_t *)data; impl->alloclen = length; impl->realloc = NULL; impl->realloc_func_ctx = NULL; return true; } bson_t * bson_new (void) { bson_impl_inline_t *impl; bson_t *bson; bson = bson_malloc (sizeof *bson); impl = (bson_impl_inline_t *)bson; impl->flags = BSON_FLAG_INLINE; impl->len = 5; impl->data[0] = 5; impl->data[1] = 0; impl->data[2] = 0; impl->data[3] = 0; impl->data[4] = 0; return bson; } bson_t * bson_sized_new (size_t size) { bson_impl_alloc_t *impl_a; bson_impl_inline_t *impl_i; bson_t *b; BSON_ASSERT (size <= INT32_MAX); b = bson_malloc (sizeof *b); impl_a = (bson_impl_alloc_t *)b; impl_i = (bson_impl_inline_t *)b; if (size <= sizeof impl_i->data) { bson_init (b); b->flags &= ~BSON_FLAG_STATIC; } else { impl_a->flags = BSON_FLAG_NONE; impl_a->len = 5; impl_a->parent = NULL; impl_a->depth = 0; impl_a->buf = &impl_a->alloc; impl_a->buflen = &impl_a->alloclen; impl_a->offset = 0; impl_a->alloclen = BSON_MAX (5, size); impl_a->alloc = bson_malloc (impl_a->alloclen); impl_a->alloc[0] = 5; impl_a->alloc[1] = 0; impl_a->alloc[2] = 0; impl_a->alloc[3] = 0; impl_a->alloc[4] = 0; impl_a->realloc = bson_realloc_ctx; impl_a->realloc_func_ctx = NULL; } return b; } bson_t * bson_new_from_data (const uint8_t *data, size_t length) { uint32_t len_le; bson_t *bson; BSON_ASSERT (data); if ((length < 5) || (length > INT_MAX) || data [length - 1]) { return NULL; } memcpy (&len_le, data, sizeof (len_le)); if (length != (size_t)BSON_UINT32_FROM_LE (len_le)) { return NULL; } bson = bson_sized_new (length); memcpy (_bson_data (bson), data, length); bson->len = (uint32_t)length; return bson; } bson_t * bson_new_from_buffer (uint8_t **buf, size_t *buf_len, bson_realloc_func realloc_func, void *realloc_func_ctx) { bson_impl_alloc_t *impl; uint32_t len_le; uint32_t length; bson_t *bson; BSON_ASSERT (buf); BSON_ASSERT (buf_len); if (!realloc_func) { realloc_func = bson_realloc_ctx; } bson = bson_malloc0 (sizeof *bson); impl = (bson_impl_alloc_t *)bson; if (!*buf) { length = 5; len_le = BSON_UINT32_TO_LE (length); *buf_len = 5; *buf = realloc_func (*buf, *buf_len, realloc_func_ctx); memcpy (*buf, &len_le, sizeof (len_le)); (*buf) [4] = '\0'; } else { if ((*buf_len < 5) || (*buf_len > INT_MAX)) { bson_free (bson); return NULL; } memcpy (&len_le, *buf, sizeof (len_le)); length = BSON_UINT32_FROM_LE(len_le); } if ((*buf)[length - 1]) { bson_free (bson); return NULL; } impl->flags = BSON_FLAG_NO_FREE; impl->len = length; impl->buf = buf; impl->buflen = buf_len; impl->realloc = realloc_func; impl->realloc_func_ctx = realloc_func_ctx; return bson; } bson_t * bson_copy (const bson_t *bson) { const uint8_t *data; BSON_ASSERT (bson); data = _bson_data (bson); return bson_new_from_data (data, bson->len); } void bson_copy_to (const bson_t *src, bson_t *dst) { const uint8_t *data; bson_impl_alloc_t *adst; size_t len; BSON_ASSERT (src); BSON_ASSERT (dst); if ((src->flags & BSON_FLAG_INLINE)) { memcpy (dst, src, sizeof *dst); dst->flags = (BSON_FLAG_STATIC | BSON_FLAG_INLINE); return; } data = _bson_data (src); len = bson_next_power_of_two ((size_t)src->len); adst = (bson_impl_alloc_t *)dst; adst->flags = BSON_FLAG_STATIC; adst->len = src->len; adst->parent = NULL; adst->depth = 0; adst->buf = &adst->alloc; adst->buflen = &adst->alloclen; adst->offset = 0; adst->alloc = bson_malloc (len); adst->alloclen = len; adst->realloc = bson_realloc_ctx; adst->realloc_func_ctx = NULL; memcpy (adst->alloc, data, src->len); } static bool should_ignore (const char *first_exclude, va_list args, const char *name) { bool ret = false; const char *exclude = first_exclude; va_list args_copy; va_copy (args_copy, args); do { if (!strcmp (name, exclude)) { ret = true; break; } } while ((exclude = va_arg (args_copy, const char *))); va_end (args_copy); return ret; } static void _bson_copy_to_excluding_va (const bson_t *src, bson_t *dst, const char *first_exclude, va_list args) { bson_iter_t iter; if (bson_iter_init (&iter, src)) { while (bson_iter_next (&iter)) { if (!should_ignore (first_exclude, args, bson_iter_key (&iter))) { if (!bson_append_iter (dst, NULL, 0, &iter)) { /* * This should not be able to happen since we are copying * from within a valid bson_t. */ BSON_ASSERT (false); return; } } } } } void bson_copy_to_excluding (const bson_t *src, bson_t *dst, const char *first_exclude, ...) { va_list args; BSON_ASSERT (src); BSON_ASSERT (dst); BSON_ASSERT (first_exclude); bson_init (dst); va_start (args, first_exclude); _bson_copy_to_excluding_va (src, dst, first_exclude, args); va_end (args); } void bson_copy_to_excluding_noinit (const bson_t *src, bson_t *dst, const char *first_exclude, ...) { va_list args; BSON_ASSERT (src); BSON_ASSERT (dst); BSON_ASSERT (first_exclude); va_start (args, first_exclude); _bson_copy_to_excluding_va (src, dst, first_exclude, args); va_end (args); } void bson_destroy (bson_t *bson) { BSON_ASSERT (bson); if (!(bson->flags & (BSON_FLAG_RDONLY | BSON_FLAG_INLINE | BSON_FLAG_NO_FREE))) { bson_free (*((bson_impl_alloc_t *)bson)->buf); } if (!(bson->flags & BSON_FLAG_STATIC)) { bson_free (bson); } } uint8_t * bson_destroy_with_steal (bson_t *bson, bool steal, uint32_t *length) { uint8_t *ret = NULL; BSON_ASSERT (bson); if (length) { *length = bson->len; } if (!steal) { bson_destroy (bson); return NULL; } if ((bson->flags & (BSON_FLAG_CHILD | BSON_FLAG_IN_CHILD | BSON_FLAG_RDONLY))) { /* Do nothing */ } else if ((bson->flags & BSON_FLAG_INLINE)) { bson_impl_inline_t *inl; inl = (bson_impl_inline_t *)bson; ret = bson_malloc (bson->len); memcpy (ret, inl->data, bson->len); } else { bson_impl_alloc_t *alloc; alloc = (bson_impl_alloc_t *)bson; ret = *alloc->buf; *alloc->buf = NULL; } bson_destroy (bson); return ret; } const uint8_t * bson_get_data (const bson_t *bson) { BSON_ASSERT (bson); return _bson_data (bson); } uint32_t bson_count_keys (const bson_t *bson) { uint32_t count = 0; bson_iter_t iter; BSON_ASSERT (bson); if (bson_iter_init (&iter, bson)) { while (bson_iter_next (&iter)) { count++; } } return count; } bool bson_has_field (const bson_t *bson, const char *key) { bson_iter_t iter; bson_iter_t child; BSON_ASSERT (bson); BSON_ASSERT (key); if (NULL != strchr (key, '.')) { return (bson_iter_init (&iter, bson) && bson_iter_find_descendant (&iter, key, &child)); } return bson_iter_init_find (&iter, bson, key); } int bson_compare (const bson_t *bson, const bson_t *other) { const uint8_t *data1; const uint8_t *data2; size_t len1; size_t len2; int64_t ret; data1 = _bson_data (bson) + 4; len1 = bson->len - 4; data2 = _bson_data (other) + 4; len2 = other->len - 4; if (len1 == len2) { return memcmp (data1, data2, len1); } ret = memcmp (data1, data2, BSON_MIN (len1, len2)); if (ret == 0) { ret = (int64_t) (len1 - len2); } return (ret < 0) ? -1 : (ret > 0); } bool bson_equal (const bson_t *bson, const bson_t *other) { return !bson_compare (bson, other); } static bool _bson_as_json_visit_utf8 (const bson_iter_t *iter, const char *key, size_t v_utf8_len, const char *v_utf8, void *data) { bson_json_state_t *state = data; char *escaped; escaped = bson_utf8_escape_for_json (v_utf8, v_utf8_len); if (escaped) { bson_string_append (state->str, "\""); bson_string_append (state->str, escaped); bson_string_append (state->str, "\""); bson_free (escaped); return false; } return true; } static bool _bson_as_json_visit_int32 (const bson_iter_t *iter, const char *key, int32_t v_int32, void *data) { bson_json_state_t *state = data; bson_string_append_printf (state->str, "%" PRId32, v_int32); return false; } static bool _bson_as_json_visit_int64 (const bson_iter_t *iter, const char *key, int64_t v_int64, void *data) { bson_json_state_t *state = data; bson_string_append_printf (state->str, "%" PRId64, v_int64); return false; } static bool _bson_as_json_visit_double (const bson_iter_t *iter, const char *key, double v_double, void *data) { bson_json_state_t *state = data; #ifdef BSON_NEEDS_SET_OUTPUT_FORMAT unsigned int current_format = _set_output_format(_TWO_DIGIT_EXPONENT); #endif bson_string_append_printf (state->str, "%.15g", v_double); #ifdef BSON_NEEDS_SET_OUTPUT_FORMAT _set_output_format(current_format); #endif return false; } static bool _bson_as_json_visit_undefined (const bson_iter_t *iter, const char *key, void *data) { bson_json_state_t *state = data; bson_string_append (state->str, "{ \"$undefined\" : true }"); return false; } static bool _bson_as_json_visit_null (const bson_iter_t *iter, const char *key, void *data) { bson_json_state_t *state = data; bson_string_append (state->str, "null"); return false; } static bool _bson_as_json_visit_oid (const bson_iter_t *iter, const char *key, const bson_oid_t *oid, void *data) { bson_json_state_t *state = data; char str[25]; bson_oid_to_string (oid, str); bson_string_append (state->str, "{ \"$oid\" : \""); bson_string_append (state->str, str); bson_string_append (state->str, "\" }"); return false; } static bool _bson_as_json_visit_binary (const bson_iter_t *iter, const char *key, bson_subtype_t v_subtype, size_t v_binary_len, const uint8_t *v_binary, void *data) { bson_json_state_t *state = data; size_t b64_len; char *b64; b64_len = (v_binary_len / 3 + 1) * 4 + 1; b64 = bson_malloc0 (b64_len); b64_ntop (v_binary, v_binary_len, b64, b64_len); bson_string_append (state->str, "{ \"$type\" : \""); bson_string_append_printf (state->str, "%02x", v_subtype); bson_string_append (state->str, "\", \"$binary\" : \""); bson_string_append (state->str, b64); bson_string_append (state->str, "\" }"); bson_free (b64); return false; } static bool _bson_as_json_visit_bool (const bson_iter_t *iter, const char *key, bool v_bool, void *data) { bson_json_state_t *state = data; bson_string_append (state->str, v_bool ? "true" : "false"); return false; } static bool _bson_as_json_visit_date_time (const bson_iter_t *iter, const char *key, int64_t msec_since_epoch, void *data) { bson_json_state_t *state = data; bson_string_append (state->str, "{ \"$date\" : "); bson_string_append_printf (state->str, "%" PRId64, msec_since_epoch); bson_string_append (state->str, " }"); return false; } static bool _bson_as_json_visit_regex (const bson_iter_t *iter, const char *key, const char *v_regex, const char *v_options, void *data) { bson_json_state_t *state = data; bson_string_append (state->str, "{ \"$regex\" : \""); bson_string_append (state->str, v_regex); bson_string_append (state->str, "\", \"$options\" : \""); bson_string_append (state->str, v_options); bson_string_append (state->str, "\" }"); return false; } static bool _bson_as_json_visit_timestamp (const bson_iter_t *iter, const char *key, uint32_t v_timestamp, uint32_t v_increment, void *data) { bson_json_state_t *state = data; bson_string_append (state->str, "{ \"$timestamp\" : { \"t\" : "); bson_string_append_printf (state->str, "%u", v_timestamp); bson_string_append (state->str, ", \"i\" : "); bson_string_append_printf (state->str, "%u", v_increment); bson_string_append (state->str, " } }"); return false; } static bool _bson_as_json_visit_dbpointer (const bson_iter_t *iter, const char *key, size_t v_collection_len, const char *v_collection, const bson_oid_t *v_oid, void *data) { bson_json_state_t *state = data; char str[25]; bson_string_append (state->str, "{ \"$ref\" : \""); bson_string_append (state->str, v_collection); bson_string_append (state->str, "\""); if (v_oid) { bson_oid_to_string (v_oid, str); bson_string_append (state->str, ", \"$id\" : \""); bson_string_append (state->str, str); bson_string_append (state->str, "\""); } bson_string_append (state->str, " }"); return false; } static bool _bson_as_json_visit_minkey (const bson_iter_t *iter, const char *key, void *data) { bson_json_state_t *state = data; bson_string_append (state->str, "{ \"$minKey\" : 1 }"); return false; } static bool _bson_as_json_visit_maxkey (const bson_iter_t *iter, const char *key, void *data) { bson_json_state_t *state = data; bson_string_append (state->str, "{ \"$maxKey\" : 1 }"); return false; } static bool _bson_as_json_visit_before (const bson_iter_t *iter, const char *key, void *data) { bson_json_state_t *state = data; char *escaped; if (state->count) { bson_string_append (state->str, ", "); } if (state->keys) { escaped = bson_utf8_escape_for_json (key, -1); if (escaped) { bson_string_append (state->str, "\""); bson_string_append (state->str, escaped); bson_string_append (state->str, "\" : "); bson_free (escaped); } else { return true; } } state->count++; return false; } static bool _bson_as_json_visit_code (const bson_iter_t *iter, const char *key, size_t v_code_len, const char *v_code, void *data) { bson_json_state_t *state = data; char *escaped; escaped = bson_utf8_escape_for_json (v_code, v_code_len); if (escaped) { bson_string_append (state->str, "\""); bson_string_append (state->str, escaped); bson_string_append (state->str, "\""); bson_free (escaped); return false; } return true; } static bool _bson_as_json_visit_symbol (const bson_iter_t *iter, const char *key, size_t v_symbol_len, const char *v_symbol, void *data) { bson_json_state_t *state = data; bson_string_append (state->str, "\""); bson_string_append (state->str, v_symbol); bson_string_append (state->str, "\""); return false; } static bool _bson_as_json_visit_codewscope (const bson_iter_t *iter, const char *key, size_t v_code_len, const char *v_code, const bson_t *v_scope, void *data) { bson_json_state_t *state = data; char *escaped; escaped = bson_utf8_escape_for_json (v_code, v_code_len); if (escaped) { bson_string_append (state->str, "\""); bson_string_append (state->str, escaped); bson_string_append (state->str, "\""); bson_free (escaped); return false; } return true; } static const bson_visitor_t bson_as_json_visitors = { _bson_as_json_visit_before, NULL, /* visit_after */ NULL, /* visit_corrupt */ _bson_as_json_visit_double, _bson_as_json_visit_utf8, _bson_as_json_visit_document, _bson_as_json_visit_array, _bson_as_json_visit_binary, _bson_as_json_visit_undefined, _bson_as_json_visit_oid, _bson_as_json_visit_bool, _bson_as_json_visit_date_time, _bson_as_json_visit_null, _bson_as_json_visit_regex, _bson_as_json_visit_dbpointer, _bson_as_json_visit_code, _bson_as_json_visit_symbol, _bson_as_json_visit_codewscope, _bson_as_json_visit_int32, _bson_as_json_visit_timestamp, _bson_as_json_visit_int64, _bson_as_json_visit_maxkey, _bson_as_json_visit_minkey, }; static bool _bson_as_json_visit_document (const bson_iter_t *iter, const char *key, const bson_t *v_document, void *data) { bson_json_state_t *state = data; bson_json_state_t child_state = { 0, true }; bson_iter_t child; if (state->depth >= BSON_MAX_RECURSION) { bson_string_append (state->str, "{ ... }"); return false; } if (bson_iter_init (&child, v_document)) { child_state.str = bson_string_new ("{ "); child_state.depth = state->depth + 1; bson_iter_visit_all (&child, &bson_as_json_visitors, &child_state); bson_string_append (child_state.str, " }"); bson_string_append (state->str, child_state.str->str); bson_string_free (child_state.str, true); } return false; } static bool _bson_as_json_visit_array (const bson_iter_t *iter, const char *key, const bson_t *v_array, void *data) { bson_json_state_t *state = data; bson_json_state_t child_state = { 0, false }; bson_iter_t child; if (state->depth >= BSON_MAX_RECURSION) { bson_string_append (state->str, "{ ... }"); return false; } if (bson_iter_init (&child, v_array)) { child_state.str = bson_string_new ("[ "); child_state.depth = state->depth + 1; bson_iter_visit_all (&child, &bson_as_json_visitors, &child_state); bson_string_append (child_state.str, " ]"); bson_string_append (state->str, child_state.str->str); bson_string_free (child_state.str, true); } return false; } char * bson_as_json (const bson_t *bson, size_t *length) { bson_json_state_t state; bson_iter_t iter; BSON_ASSERT (bson); if (length) { *length = 0; } if (bson_empty0 (bson)) { if (length) { *length = 3; } return bson_strdup ("{ }"); } if (!bson_iter_init (&iter, bson)) { return NULL; } state.count = 0; state.keys = true; state.str = bson_string_new ("{ "); state.depth = 0; if (bson_iter_visit_all (&iter, &bson_as_json_visitors, &state) || iter.err_off) { /* * We were prematurely exited due to corruption or failed visitor. */ bson_string_free (state.str, true); if (length) { *length = 0; } return NULL; } bson_string_append (state.str, " }"); if (length) { *length = state.str->len; } return bson_string_free (state.str, false); } char * bson_array_as_json (const bson_t *bson, size_t *length) { bson_json_state_t state; bson_iter_t iter; BSON_ASSERT (bson); if (length) { *length = 0; } if (bson_empty0 (bson)) { if (length) { *length = 3; } return bson_strdup ("[ ]"); } if (!bson_iter_init (&iter, bson)) { return NULL; } state.count = 0; state.keys = false; state.str = bson_string_new ("[ "); state.depth = 0; bson_iter_visit_all (&iter, &bson_as_json_visitors, &state); if (bson_iter_visit_all (&iter, &bson_as_json_visitors, &state) || iter.err_off) { /* * We were prematurely exited due to corruption or failed visitor. */ bson_string_free (state.str, true); if (length) { *length = 0; } return NULL; } bson_string_append (state.str, " ]"); if (length) { *length = state.str->len; } return bson_string_free (state.str, false); } static bool _bson_iter_validate_utf8 (const bson_iter_t *iter, const char *key, size_t v_utf8_len, const char *v_utf8, void *data) { bson_validate_state_t *state = data; bool allow_null; if ((state->flags & BSON_VALIDATE_UTF8)) { allow_null = !!(state->flags & BSON_VALIDATE_UTF8_ALLOW_NULL); if (!bson_utf8_validate (v_utf8, v_utf8_len, allow_null)) { state->err_offset = iter->off; return true; } } if ((state->flags & BSON_VALIDATE_DOLLAR_KEYS)) { if (state->phase == BSON_VALIDATE_PHASE_LF_REF_UTF8) { state->phase = BSON_VALIDATE_PHASE_LF_ID_KEY; } else if (state->phase == BSON_VALIDATE_PHASE_LF_DB_UTF8) { state->phase = BSON_VALIDATE_PHASE_NOT_DBREF; } } return false; } static void _bson_iter_validate_corrupt (const bson_iter_t *iter, void *data) { bson_validate_state_t *state = data; state->err_offset = iter->err_off; } static bool _bson_iter_validate_before (const bson_iter_t *iter, const char *key, void *data) { bson_validate_state_t *state = data; if ((state->flags & BSON_VALIDATE_DOLLAR_KEYS)) { if (key[0] == '$') { if (state->phase == BSON_VALIDATE_PHASE_LF_REF_KEY && strcmp (key, "$ref") == 0) { state->phase = BSON_VALIDATE_PHASE_LF_REF_UTF8; } else if (state->phase == BSON_VALIDATE_PHASE_LF_ID_KEY && strcmp (key, "$id") == 0) { state->phase = BSON_VALIDATE_PHASE_LF_DB_KEY; } else if (state->phase == BSON_VALIDATE_PHASE_LF_DB_KEY && strcmp (key, "$db") == 0) { state->phase = BSON_VALIDATE_PHASE_LF_DB_UTF8; } else { state->err_offset = iter->off; return true; } } else if (state->phase == BSON_VALIDATE_PHASE_LF_ID_KEY || state->phase == BSON_VALIDATE_PHASE_LF_REF_UTF8 || state->phase == BSON_VALIDATE_PHASE_LF_DB_UTF8) { state->err_offset = iter->off; return true; } else { state->phase = BSON_VALIDATE_PHASE_NOT_DBREF; } } if ((state->flags & BSON_VALIDATE_DOT_KEYS)) { if (strstr (key, ".")) { state->err_offset = iter->off; return true; } } return false; } static bool _bson_iter_validate_codewscope (const bson_iter_t *iter, const char *key, size_t v_code_len, const char *v_code, const bson_t *v_scope, void *data) { bson_validate_state_t *state = data; size_t offset; if (!bson_validate (v_scope, state->flags, &offset)) { state->err_offset = iter->off + offset; return false; } return true; } static bool _bson_iter_validate_document (const bson_iter_t *iter, const char *key, const bson_t *v_document, void *data); static const bson_visitor_t bson_validate_funcs = { _bson_iter_validate_before, NULL, /* visit_after */ _bson_iter_validate_corrupt, NULL, /* visit_double */ _bson_iter_validate_utf8, _bson_iter_validate_document, _bson_iter_validate_document, /* visit_array */ NULL, /* visit_binary */ NULL, /* visit_undefined */ NULL, /* visit_oid */ NULL, /* visit_bool */ NULL, /* visit_date_time */ NULL, /* visit_null */ NULL, /* visit_regex */ NULL, /* visit_dbpoint */ NULL, /* visit_code */ NULL, /* visit_symbol */ _bson_iter_validate_codewscope, }; static bool _bson_iter_validate_document (const bson_iter_t *iter, const char *key, const bson_t *v_document, void *data) { bson_validate_state_t *state = data; bson_iter_t child; bson_validate_phase_t phase = state->phase; if (!bson_iter_init (&child, v_document)) { state->err_offset = iter->off; return true; } if (state->phase == BSON_VALIDATE_PHASE_START) { state->phase = BSON_VALIDATE_PHASE_TOP; } else { state->phase = BSON_VALIDATE_PHASE_LF_REF_KEY; } bson_iter_visit_all (&child, &bson_validate_funcs, state); if (state->phase == BSON_VALIDATE_PHASE_LF_ID_KEY || state->phase == BSON_VALIDATE_PHASE_LF_REF_UTF8 || state->phase == BSON_VALIDATE_PHASE_LF_DB_UTF8) { state->err_offset = iter->off; return true; } state->phase = phase; return false; } bool bson_validate (const bson_t *bson, bson_validate_flags_t flags, size_t *offset) { bson_validate_state_t state = { flags, -1, BSON_VALIDATE_PHASE_START }; bson_iter_t iter; if (!bson_iter_init (&iter, bson)) { state.err_offset = 0; goto failure; } _bson_iter_validate_document (&iter, NULL, bson, &state); failure: if (offset) { *offset = state.err_offset; } return state.err_offset < 0; } bool bson_concat (bson_t *dst, const bson_t *src) { BSON_ASSERT (dst); BSON_ASSERT (src); if (!bson_empty (src)) { return _bson_append (dst, 1, src->len - 5, src->len - 5, _bson_data (src) + 4); } return true; } mongodb-1.1.5/src/libbson/src/bson/bson.h0000664000175000017500000007246512673034026020105 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef BSON_H #define BSON_H #define BSON_INSIDE #include "bson-compat.h" #include #include #include "bson-macros.h" #include "bson-config.h" #include "bson-atomic.h" #include "bson-context.h" #include "bson-clock.h" #include "bson-error.h" #include "bson-iter.h" #include "bson-json.h" #include "bson-keys.h" #include "bson-md5.h" #include "bson-memory.h" #include "bson-oid.h" #include "bson-reader.h" #include "bson-string.h" #include "bson-types.h" #include "bson-utf8.h" #include "bson-value.h" #include "bson-version.h" #include "bson-version-functions.h" #include "bson-writer.h" #include "bcon.h" #undef BSON_INSIDE BSON_BEGIN_DECLS /** * bson_empty: * @b: a bson_t. * * Checks to see if @b is an empty BSON document. An empty BSON document is * a 5 byte document which contains the length (4 bytes) and a single NUL * byte indicating end of fields. */ #define bson_empty(b) (((b)->len == 5) || !bson_get_data ((b))[4]) /** * bson_empty0: * * Like bson_empty() but treats NULL the same as an empty bson_t document. */ #define bson_empty0(b) (!(b) || bson_empty (b)) /** * bson_clear: * * Easily free a bson document and set it to NULL. Use like: * * bson_t *doc = bson_new(); * bson_clear (&doc); * assert (doc == NULL); */ #define bson_clear(bptr) \ do { \ if (*(bptr)) { \ bson_destroy (*(bptr)); \ *(bptr) = NULL; \ } \ } while (0) /** * BSON_MAX_SIZE: * * The maximum size in bytes of a BSON document. */ #define BSON_MAX_SIZE ((size_t)((1U << 31) - 1)) #define BSON_APPEND_ARRAY(b,key,val) \ bson_append_array (b, key, (int)strlen (key), val) #define BSON_APPEND_ARRAY_BEGIN(b,key,child) \ bson_append_array_begin (b, key, (int)strlen (key), child) #define BSON_APPEND_BINARY(b,key,subtype,val,len) \ bson_append_binary (b, key, (int) strlen (key), subtype, val, len) #define BSON_APPEND_BOOL(b,key,val) \ bson_append_bool (b, key, (int) strlen (key), val) #define BSON_APPEND_CODE(b,key,val) \ bson_append_code (b, key, (int) strlen (key), val) #define BSON_APPEND_CODE_WITH_SCOPE(b,key,val,scope) \ bson_append_code_with_scope (b, key, (int) strlen (key), val, scope) #define BSON_APPEND_DBPOINTER(b,key,coll,oid) \ bson_append_dbpointer (b, key, (int) strlen (key), coll, oid) #define BSON_APPEND_DOCUMENT_BEGIN(b,key,child) \ bson_append_document_begin (b, key, (int)strlen (key), child) #define BSON_APPEND_DOUBLE(b,key,val) \ bson_append_double (b, key, (int) strlen (key), val) #define BSON_APPEND_DOCUMENT(b,key,val) \ bson_append_document (b, key, (int) strlen (key), val) #define BSON_APPEND_INT32(b,key,val) \ bson_append_int32 (b, key, (int) strlen (key), val) #define BSON_APPEND_INT64(b,key,val) \ bson_append_int64 (b, key, (int) strlen (key), val) #define BSON_APPEND_MINKEY(b,key) \ bson_append_minkey (b, key, (int) strlen (key)) #define BSON_APPEND_MAXKEY(b,key) \ bson_append_maxkey (b, key, (int) strlen (key)) #define BSON_APPEND_NULL(b,key) \ bson_append_null (b, key, (int) strlen (key)) #define BSON_APPEND_OID(b,key,val) \ bson_append_oid (b, key, (int) strlen (key), val) #define BSON_APPEND_REGEX(b,key,val,opt) \ bson_append_regex (b, key, (int) strlen (key), val, opt) #define BSON_APPEND_UTF8(b,key,val) \ bson_append_utf8 (b, key, (int) strlen (key), val, (int) strlen (val)) #define BSON_APPEND_SYMBOL(b,key,val) \ bson_append_symbol (b, key, (int) strlen (key), val, (int) strlen (val)) #define BSON_APPEND_TIME_T(b,key,val) \ bson_append_time_t (b, key, (int) strlen (key), val) #define BSON_APPEND_TIMEVAL(b,key,val) \ bson_append_timeval (b, key, (int) strlen (key), val) #define BSON_APPEND_DATE_TIME(b,key,val) \ bson_append_date_time (b, key, (int) strlen (key), val) #define BSON_APPEND_TIMESTAMP(b,key,val,inc) \ bson_append_timestamp (b, key, (int) strlen (key), val, inc) #define BSON_APPEND_UNDEFINED(b,key) \ bson_append_undefined (b, key, (int) strlen (key)) #define BSON_APPEND_VALUE(b,key,val) \ bson_append_value (b, key, (int) strlen (key), (val)) /** * bson_new: * * Allocates a new bson_t structure. Call the various bson_append_*() * functions to add fields to the bson. You can iterate the bson_t at any * time using a bson_iter_t and bson_iter_init(). * * Returns: A newly allocated bson_t that should be freed with bson_destroy(). */ bson_t * bson_new (void); bson_t * bson_new_from_json (const uint8_t *data, ssize_t len, bson_error_t *error); bool bson_init_from_json (bson_t *bson, const char *data, ssize_t len, bson_error_t *error); /** * bson_init_static: * @b: A pointer to a bson_t. * @data: The data buffer to use. * @length: The length of @data. * * Initializes a bson_t using @data and @length. This is ideal if you would * like to use a stack allocation for your bson and do not need to grow the * buffer. @data must be valid for the life of @b. * * Returns: true if initialized successfully; otherwise false. */ bool bson_init_static (bson_t *b, const uint8_t *data, size_t length); /** * bson_init: * @b: A pointer to a bson_t. * * Initializes a bson_t for use. This function is useful to those that want a * stack allocated bson_t. The usefulness of a stack allocated bson_t is * marginal as the target buffer for content will still require heap * allocations. It can help reduce heap fragmentation on allocators that do * not employ SLAB/magazine semantics. * * You must call bson_destroy() with @b to release resources when you are done * using @b. */ void bson_init (bson_t *b); /** * bson_reinit: * @b: (inout): A bson_t. * * This is equivalent to calling bson_destroy() and bson_init() on a #bson_t. * However, it will try to persist the existing malloc'd buffer if one exists. * This is useful in cases where you want to reduce malloc overhead while * building many documents. */ void bson_reinit (bson_t *b); /** * bson_new_from_data: * @data: A buffer containing a serialized bson document. * @length: The length of the document in bytes. * * Creates a new bson_t structure using the data provided. @data should contain * at least @length bytes that can be copied into the new bson_t structure. * * Returns: A newly allocated bson_t that should be freed with bson_destroy(). * If the first four bytes (little-endian) of data do not match @length, * then NULL will be returned. */ bson_t * bson_new_from_data (const uint8_t *data, size_t length); /** * bson_new_from_buffer: * @buf: A pointer to a buffer containing a serialized bson document. Or null * @buf_len: The length of the buffer in bytes. * @realloc_fun: a realloc like function * @realloc_fun_ctx: a context for the realloc function * * Creates a new bson_t structure using the data provided. @buf should contain * a bson document, or null pointer should be passed for new allocations. * * Returns: A newly allocated bson_t that should be freed with bson_destroy(). * The underlying buffer will be used and not be freed in destroy. */ bson_t * bson_new_from_buffer (uint8_t **buf, size_t *buf_len, bson_realloc_func realloc_func, void *realloc_func_ctx); /** * bson_sized_new: * @size: A size_t containing the number of bytes to allocate. * * This will allocate a new bson_t with enough bytes to hold a buffer * sized @size. @size must be smaller than INT_MAX bytes. * * Returns: A newly allocated bson_t that should be freed with bson_destroy(). */ bson_t * bson_sized_new (size_t size); /** * bson_copy: * @bson: A bson_t. * * Copies @bson into a newly allocated bson_t. You must call bson_destroy() * when you are done with the resulting value to free its resources. * * Returns: A newly allocated bson_t that should be free'd with bson_destroy() */ bson_t * bson_copy (const bson_t *bson); /** * bson_copy_to: * @src: The source bson_t. * @dst: The destination bson_t. * * Initializes @dst and copies the content from @src into @dst. */ void bson_copy_to (const bson_t *src, bson_t *dst); /** * bson_copy_to_excluding: * @src: A bson_t. * @dst: A bson_t to initialize and copy into. * @first_exclude: First field name to exclude. * * Copies @src into @dst excluding any field that is provided. * This is handy for situations when you need to remove one or * more fields in a bson_t. Note that bson_init() will be called * on dst. */ void bson_copy_to_excluding (const bson_t *src, bson_t *dst, const char *first_exclude, ...) BSON_GNUC_NULL_TERMINATED BSON_GNUC_DEPRECATED_FOR(bson_copy_to_excluding_noinit); /** * bson_copy_to_excluding_noinit: * @src: A bson_t. * @dst: A bson_t to initialize and copy into. * @first_exclude: First field name to exclude. * * The same as bson_copy_to_excluding, but does not call bson_init() * on the dst. This version should be preferred in new code, but the * old function is left for backwards compatibility. */ void bson_copy_to_excluding_noinit (const bson_t *src, bson_t *dst, const char *first_exclude, ...) BSON_GNUC_NULL_TERMINATED; /** * bson_destroy: * @bson: A bson_t. * * Frees the resources associated with @bson. */ void bson_destroy (bson_t *bson); /** * bson_destroy_with_steal: * @bson: A #bson_t. * @steal: If ownership of the data buffer should be transfered to caller. * @length: (out): location for the length of the buffer. * * Destroys @bson similar to calling bson_destroy() except that the underlying * buffer will be returned and ownership transfered to the caller if @steal * is non-zero. * * If length is non-NULL, the length of @bson will be stored in @length. * * It is a programming error to call this function with any bson that has * been initialized static, or is being used to create a subdocument with * functions such as bson_append_document_begin() or bson_append_array_begin(). * * Returns: a buffer owned by the caller if @steal is true. Otherwise NULL. * If there was an error, NULL is returned. */ uint8_t * bson_destroy_with_steal (bson_t *bson, bool steal, uint32_t *length); /** * bson_get_data: * @bson: A bson_t. * * Fetched the data buffer for @bson of @bson->len bytes in length. * * Returns: A buffer that should not be modified or freed. */ const uint8_t * bson_get_data (const bson_t *bson); /** * bson_count_keys: * @bson: A bson_t. * * Counts the number of elements found in @bson. */ uint32_t bson_count_keys (const bson_t *bson); /** * bson_has_field: * @bson: A bson_t. * @key: The key to lookup. * * Checks to see if @bson contains a field named @key. * * This function is case-sensitive. * * Returns: true if @key exists in @bson; otherwise false. */ bool bson_has_field (const bson_t *bson, const char *key); /** * bson_compare: * @bson: A bson_t. * @other: A bson_t. * * Compares @bson to @other in a qsort() style comparison. * See qsort() for information on how this function works. * * Returns: Less than zero, zero, or greater than zero. */ int bson_compare (const bson_t *bson, const bson_t *other); /* * bson_compare: * @bson: A bson_t. * @other: A bson_t. * * Checks to see if @bson and @other are equal. * * Returns: true if equal; otherwise false. */ bool bson_equal (const bson_t *bson, const bson_t *other); /** * bson_validate: * @bson: A bson_t. * @offset: A location for the error offset. * * Validates a BSON document by walking through the document and inspecting * the fields for valid content. * * Returns: true if @bson is valid; otherwise false and @offset is set. */ bool bson_validate (const bson_t *bson, bson_validate_flags_t flags, size_t *offset); /** * bson_as_json: * @bson: A bson_t. * @length: A location for the string length, or NULL. * * Creates a new string containing @bson in extended JSON format. The caller * is responsible for freeing the resulting string. If @length is non-NULL, * then the length of the resulting string will be placed in @length. * * See http://docs.mongodb.org/manual/reference/mongodb-extended-json/ for * more information on extended JSON. * * Returns: A newly allocated string that should be freed with bson_free(). */ char * bson_as_json (const bson_t *bson, size_t *length); /* like bson_as_json() but for outermost arrays. */ char * bson_array_as_json (const bson_t *bson, size_t *length); bool bson_append_value (bson_t *bson, const char *key, int key_length, const bson_value_t *value); /** * bson_append_array: * @bson: A bson_t. * @key: The key for the field. * @array: A bson_t containing the array. * * Appends a BSON array to @bson. BSON arrays are like documents where the * key is the string version of the index. For example, the first item of the * array would have the key "0". The second item would have the index "1". * * Returns: true if successful; false if append would overflow max size. */ bool bson_append_array (bson_t *bson, const char *key, int key_length, const bson_t *array); /** * bson_append_binary: * @bson: A bson_t to append. * @key: The key for the field. * @subtype: The bson_subtype_t of the binary. * @binary: The binary buffer to append. * @length: The length of @binary. * * Appends a binary buffer to the BSON document. * * Returns: true if successful; false if append would overflow max size. */ bool bson_append_binary (bson_t *bson, const char *key, int key_length, bson_subtype_t subtype, const uint8_t *binary, uint32_t length); /** * bson_append_bool: * @bson: A bson_t. * @key: The key for the field. * @value: The boolean value. * * Appends a new field to @bson of type BSON_TYPE_BOOL. * * Returns: true if successful; false if append would overflow max size. */ bool bson_append_bool (bson_t *bson, const char *key, int key_length, bool value); /** * bson_append_code: * @bson: A bson_t. * @key: The key for the document. * @javascript: JavaScript code to be executed. * * Appends a field of type BSON_TYPE_CODE to the BSON document. @javascript * should contain a script in javascript to be executed. * * Returns: true if successful; false if append would overflow max size. */ bool bson_append_code (bson_t *bson, const char *key, int key_length, const char *javascript); /** * bson_append_code_with_scope: * @bson: A bson_t. * @key: The key for the document. * @javascript: JavaScript code to be executed. * @scope: A bson_t containing the scope for @javascript. * * Appends a field of type BSON_TYPE_CODEWSCOPE to the BSON document. * @javascript should contain a script in javascript to be executed. * * Returns: true if successful; false if append would overflow max size. */ bool bson_append_code_with_scope (bson_t *bson, const char *key, int key_length, const char *javascript, const bson_t *scope); /** * bson_append_dbpointer: * @bson: A bson_t. * @key: The key for the field. * @collection: The collection name. * @oid: The oid to the reference. * * Appends a new field of type BSON_TYPE_DBPOINTER. This datum type is * deprecated in the BSON spec and should not be used in new code. * * Returns: true if successful; false if append would overflow max size. */ bool bson_append_dbpointer (bson_t *bson, const char *key, int key_length, const char *collection, const bson_oid_t *oid); /** * bson_append_double: * @bson: A bson_t. * @key: The key for the field. * * Appends a new field to @bson of the type BSON_TYPE_DOUBLE. * * Returns: true if successful; false if append would overflow max size. */ bool bson_append_double (bson_t *bson, const char *key, int key_length, double value); /** * bson_append_document: * @bson: A bson_t. * @key: The key for the field. * @value: A bson_t containing the subdocument. * * Appends a new field to @bson of the type BSON_TYPE_DOCUMENT. * The documents contents will be copied into @bson. * * Returns: true if successful; false if append would overflow max size. */ bool bson_append_document (bson_t *bson, const char *key, int key_length, const bson_t *value); /** * bson_append_document_begin: * @bson: A bson_t. * @key: The key for the field. * @key_length: The length of @key in bytes not including NUL or -1 * if @key_length is NUL terminated. * @child: A location to an uninitialized bson_t. * * Appends a new field named @key to @bson. The field is, however, * incomplete. @child will be initialized so that you may add fields to the * child document. Child will use a memory buffer owned by @bson and * therefore grow the parent buffer as additional space is used. This allows * a single malloc'd buffer to be used when building documents which can help * reduce memory fragmentation. * * Returns: true if successful; false if append would overflow max size. */ bool bson_append_document_begin (bson_t *bson, const char *key, int key_length, bson_t *child); /** * bson_append_document_end: * @bson: A bson_t. * @child: A bson_t supplied to bson_append_document_begin(). * * Finishes the appending of a document to a @bson. @child is considered * disposed after this call and should not be used any further. * * Returns: true if successful; false if append would overflow max size. */ bool bson_append_document_end (bson_t *bson, bson_t *child); /** * bson_append_array_begin: * @bson: A bson_t. * @key: The key for the field. * @key_length: The length of @key in bytes not including NUL or -1 * if @key_length is NUL terminated. * @child: A location to an uninitialized bson_t. * * Appends a new field named @key to @bson. The field is, however, * incomplete. @child will be initialized so that you may add fields to the * child array. Child will use a memory buffer owned by @bson and * therefore grow the parent buffer as additional space is used. This allows * a single malloc'd buffer to be used when building arrays which can help * reduce memory fragmentation. * * The type of @child will be BSON_TYPE_ARRAY and therefore the keys inside * of it MUST be "0", "1", etc. * * Returns: true if successful; false if append would overflow max size. */ bool bson_append_array_begin (bson_t *bson, const char *key, int key_length, bson_t *child); /** * bson_append_array_end: * @bson: A bson_t. * @child: A bson_t supplied to bson_append_array_begin(). * * Finishes the appending of a array to a @bson. @child is considered * disposed after this call and should not be used any further. * * Returns: true if successful; false if append would overflow max size. */ bool bson_append_array_end (bson_t *bson, bson_t *child); /** * bson_append_int32: * @bson: A bson_t. * @key: The key for the field. * @value: The int32_t 32-bit integer value. * * Appends a new field of type BSON_TYPE_INT32 to @bson. * * Returns: true if successful; false if append would overflow max size. */ bool bson_append_int32 (bson_t *bson, const char *key, int key_length, int32_t value); /** * bson_append_int64: * @bson: A bson_t. * @key: The key for the field. * @value: The int64_t 64-bit integer value. * * Appends a new field of type BSON_TYPE_INT64 to @bson. * * Returns: true if successful; false if append would overflow max size. */ bool bson_append_int64 (bson_t *bson, const char *key, int key_length, int64_t value); /** * bson_append_iter: * @bson: A bson_t to append to. * @key: The key name or %NULL to take current key from @iter. * @key_length: The key length or -1 to use strlen(). * @iter: The iter located on the position of the element to append. * * Appends a new field to @bson that is equivalent to the field currently * pointed to by @iter. * * Returns: true if successful; false if append would overflow max size. */ bool bson_append_iter (bson_t *bson, const char *key, int key_length, const bson_iter_t *iter); /** * bson_append_minkey: * @bson: A bson_t. * @key: The key for the field. * * Appends a new field of type BSON_TYPE_MINKEY to @bson. This is a special * type that compares lower than all other possible BSON element values. * * See http://bsonspec.org for more information on this type. * * Returns: true if successful; false if append would overflow max size. */ bool bson_append_minkey (bson_t *bson, const char *key, int key_length); /** * bson_append_maxkey: * @bson: A bson_t. * @key: The key for the field. * * Appends a new field of type BSON_TYPE_MAXKEY to @bson. This is a special * type that compares higher than all other possible BSON element values. * * See http://bsonspec.org for more information on this type. * * Returns: true if successful; false if append would overflow max size. */ bool bson_append_maxkey (bson_t *bson, const char *key, int key_length); /** * bson_append_null: * @bson: A bson_t. * @key: The key for the field. * * Appends a new field to @bson with NULL for the value. * * Returns: true if successful; false if append would overflow max size. */ bool bson_append_null (bson_t *bson, const char *key, int key_length); /** * bson_append_oid: * @bson: A bson_t. * @key: The key for the field. * @oid: bson_oid_t. * * Appends a new field to the @bson of type BSON_TYPE_OID using the contents of * @oid. * * Returns: true if successful; false if append would overflow max size. */ bool bson_append_oid (bson_t *bson, const char *key, int key_length, const bson_oid_t *oid); /** * bson_append_regex: * @bson: A bson_t. * @key: The key of the field. * @regex: The regex to append to the bson. * @options: Options for @regex. * * Appends a new field to @bson of type BSON_TYPE_REGEX. @regex should * be the regex string. @options should contain the options for the regex. * * Valid options for @options are: * * 'i' for case-insensitive. * 'm' for multiple matching. * 'x' for verbose mode. * 'l' to make \w and \W locale dependent. * 's' for dotall mode ('.' matches everything) * 'u' to make \w and \W match unicode. * * For more information on what comprimises a BSON regex, see bsonspec.org. * * Returns: true if successful; false if append would overflow max size. */ bool bson_append_regex (bson_t *bson, const char *key, int key_length, const char *regex, const char *options); /** * bson_append_utf8: * @bson: A bson_t. * @key: The key for the field. * @value: A UTF-8 encoded string. * @length: The length of @value or -1 if it is NUL terminated. * * Appends a new field to @bson using @key as the key and @value as the UTF-8 * encoded value. * * It is the callers responsibility to ensure @value is valid UTF-8. You can * use bson_utf8_validate() to perform this check. * * Returns: true if successful; false if append would overflow max size. */ bool bson_append_utf8 (bson_t *bson, const char *key, int key_length, const char *value, int length); /** * bson_append_symbol: * @bson: A bson_t. * @key: The key for the field. * @value: The symbol as a string. * @length: The length of @value or -1 if NUL-terminated. * * Appends a new field to @bson of type BSON_TYPE_SYMBOL. This BSON type is * deprecated and should not be used in new code. * * See http://bsonspec.org for more information on this type. * * Returns: true if successful; false if append would overflow max size. */ bool bson_append_symbol (bson_t *bson, const char *key, int key_length, const char *value, int length); /** * bson_append_time_t: * @bson: A bson_t. * @key: The key for the field. * @value: A time_t. * * Appends a BSON_TYPE_DATE_TIME field to @bson using the time_t @value for the * number of seconds since UNIX epoch in UTC. * * Returns: true if successful; false if append would overflow max size. */ bool bson_append_time_t (bson_t *bson, const char *key, int key_length, time_t value); /** * bson_append_timeval: * @bson: A bson_t. * @key: The key for the field. * @value: A struct timeval containing the date and time. * * Appends a BSON_TYPE_DATE_TIME field to @bson using the struct timeval * provided. The time is persisted in milliseconds since the UNIX epoch in UTC. * * Returns: true if successful; false if append would overflow max size. */ bool bson_append_timeval (bson_t *bson, const char *key, int key_length, struct timeval *value); /** * bson_append_date_time: * @bson: A bson_t. * @key: The key for the field. * @key_length: The length of @key in bytes or -1 if \0 terminated. * @value: The number of milliseconds elapsed since UNIX epoch. * * Appends a new field to @bson of type BSON_TYPE_DATE_TIME. * * Returns: true if sucessful; otherwise false. */ bool bson_append_date_time (bson_t *bson, const char *key, int key_length, int64_t value); /** * bson_append_now_utc: * @bson: A bson_t. * @key: The key for the field. * @key_length: The length of @key or -1 if it is NULL terminated. * * Appends a BSON_TYPE_DATE_TIME field to @bson using the current time in UTC * as the field value. * * Returns: true if successful; false if append would overflow max size. */ bool bson_append_now_utc (bson_t *bson, const char *key, int key_length); /** * bson_append_timestamp: * @bson: A bson_t. * @key: The key for the field. * @timestamp: 4 byte timestamp. * @increment: 4 byte increment for timestamp. * * Appends a field of type BSON_TYPE_TIMESTAMP to @bson. This is a special type * used by MongoDB replication and sharding. If you need generic time and date * fields use bson_append_time_t() or bson_append_timeval(). * * Setting @increment and @timestamp to zero has special semantics. See * http://bsonspec.org for more information on this field type. * * Returns: true if successful; false if append would overflow max size. */ bool bson_append_timestamp (bson_t *bson, const char *key, int key_length, uint32_t timestamp, uint32_t increment); /** * bson_append_undefined: * @bson: A bson_t. * @key: The key for the field. * * Appends a field of type BSON_TYPE_UNDEFINED. This type is deprecated in the * spec and should not be used for new code. However, it is provided for those * needing to interact with legacy systems. * * Returns: true if successful; false if append would overflow max size. */ bool bson_append_undefined (bson_t *bson, const char *key, int key_length); bool bson_concat (bson_t *dst, const bson_t *src); BSON_END_DECLS #endif /* BSON_H */ mongodb-1.1.5/src/libbson/src/yajl/yajl.c0000664000175000017500000001152612673034026020063 0ustar jmikolajmikola/* * Copyright (c) 2007-2011, Lloyd Hilaiel * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "yajl_parse.h" #include "yajl_lex.h" #include "yajl_parser.h" #include "yajl_alloc.h" #include #include #include #include const char * yajl_status_to_string(yajl_status stat) { const char * statStr = "unknown"; switch (stat) { case yajl_status_ok: statStr = "ok, no error"; break; case yajl_status_client_canceled: statStr = "client canceled parse"; break; case yajl_status_error: statStr = "parse error"; break; } return statStr; } yajl_handle yajl_alloc(const yajl_callbacks * callbacks, yajl_alloc_funcs * afs, void * ctx) { yajl_handle hand = NULL; yajl_alloc_funcs afsBuffer; /* first order of business is to set up memory allocation routines */ if (afs != NULL) { if (afs->malloc == NULL || afs->realloc == NULL || afs->free == NULL) { return NULL; } } else { yajl_set_default_alloc_funcs(&afsBuffer); afs = &afsBuffer; } hand = (yajl_handle) YA_MALLOC(afs, sizeof(struct yajl_handle_t)); /* copy in pointers to allocation routines */ memcpy((void *) &(hand->alloc), (void *) afs, sizeof(yajl_alloc_funcs)); hand->callbacks = callbacks; hand->ctx = ctx; hand->lexer = NULL; hand->bytesConsumed = 0; hand->decodeBuf = yajl_buf_alloc(&(hand->alloc)); hand->flags = 0; yajl_bs_init(hand->stateStack, &(hand->alloc)); yajl_bs_push(hand->stateStack, yajl_state_start); return hand; } int yajl_config(yajl_handle h, yajl_option opt, ...) { int rv = 1; va_list ap; va_start(ap, opt); switch(opt) { case yajl_allow_comments: case yajl_dont_validate_strings: case yajl_allow_trailing_garbage: case yajl_allow_multiple_values: case yajl_allow_partial_values: if (va_arg(ap, int)) h->flags |= opt; else h->flags &= ~opt; break; default: rv = 0; } va_end(ap); return rv; } void yajl_free(yajl_handle handle) { yajl_bs_free(handle->stateStack); yajl_buf_free(handle->decodeBuf); if (handle->lexer) { yajl_lex_free(handle->lexer); handle->lexer = NULL; } YA_FREE(&(handle->alloc), handle); } yajl_status yajl_parse(yajl_handle hand, const unsigned char * jsonText, size_t jsonTextLen) { yajl_status status; /* lazy allocation of the lexer */ if (hand->lexer == NULL) { hand->lexer = yajl_lex_alloc(&(hand->alloc), hand->flags & yajl_allow_comments, !(hand->flags & yajl_dont_validate_strings)); } status = yajl_do_parse(hand, jsonText, jsonTextLen); return status; } yajl_status yajl_complete_parse(yajl_handle hand) { /* The lexer is lazy allocated in the first call to parse. if parse is * never called, then no data was provided to parse at all. This is a * "premature EOF" error unless yajl_allow_partial_values is specified. * allocating the lexer now is the simplest possible way to handle this * case while preserving all the other semantics of the parser * (multiple values, partial values, etc). */ if (hand->lexer == NULL) { hand->lexer = yajl_lex_alloc(&(hand->alloc), hand->flags & yajl_allow_comments, !(hand->flags & yajl_dont_validate_strings)); } return yajl_do_finish(hand); } unsigned char * yajl_get_error(yajl_handle hand, int verbose, const unsigned char * jsonText, size_t jsonTextLen) { return yajl_render_error_string(hand, jsonText, jsonTextLen, verbose); } size_t yajl_get_bytes_consumed(yajl_handle hand) { if (!hand) return 0; else return hand->bytesConsumed; } void yajl_free_error(yajl_handle hand, unsigned char * str) { /* use memory allocation functions if set */ YA_FREE(&(hand->alloc), str); } /* XXX: add utility routines to parse from file */ mongodb-1.1.5/src/libbson/src/yajl/yajl_alloc.c0000664000175000017500000000270112673034026021230 0ustar jmikolajmikola/* * Copyright (c) 2007-2011, Lloyd Hilaiel * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /** * \file yajl_alloc.h * default memory allocation routines for yajl which use malloc/realloc and * free */ #include "yajl_alloc.h" #include static void * yajl_internal_malloc(void *ctx, size_t sz) { return malloc(sz); } static void * yajl_internal_realloc(void *ctx, void * previous, size_t sz) { return realloc(previous, sz); } static void yajl_internal_free(void *ctx, void * ptr) { free(ptr); } void yajl_set_default_alloc_funcs(yajl_alloc_funcs * yaf) { yaf->malloc = yajl_internal_malloc; yaf->free = yajl_internal_free; yaf->realloc = yajl_internal_realloc; yaf->ctx = NULL; } mongodb-1.1.5/src/libbson/src/yajl/yajl_alloc.h0000664000175000017500000000234312673034026021237 0ustar jmikolajmikola/* * Copyright (c) 2007-2011, Lloyd Hilaiel * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /** * \file yajl_alloc.h * default memory allocation routines for yajl which use malloc/realloc and * free */ #ifndef __YAJL_ALLOC_H__ #define __YAJL_ALLOC_H__ #include "yajl_common.h" #define YA_MALLOC(afs, sz) (afs)->malloc((afs)->ctx, (sz)) #define YA_FREE(afs, ptr) (afs)->free((afs)->ctx, (ptr)) #define YA_REALLOC(afs, ptr, sz) (afs)->realloc((afs)->ctx, (ptr), (sz)) void yajl_set_default_alloc_funcs(yajl_alloc_funcs * yaf); #endif mongodb-1.1.5/src/libbson/src/yajl/yajl_buf.c0000664000175000017500000000474012673034026020717 0ustar jmikolajmikola/* * Copyright (c) 2007-2011, Lloyd Hilaiel * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "yajl_buf.h" #include #include #include #define YAJL_BUF_INIT_SIZE 2048 struct yajl_buf_t { size_t len; size_t used; unsigned char * data; yajl_alloc_funcs * alloc; }; static void yajl_buf_ensure_available(yajl_buf buf, size_t want) { size_t need; assert(buf != NULL); /* first call */ if (buf->data == NULL) { buf->len = YAJL_BUF_INIT_SIZE; buf->data = (unsigned char *) YA_MALLOC(buf->alloc, buf->len); buf->data[0] = 0; } need = buf->len; while (want >= (need - buf->used)) need <<= 1; if (need != buf->len) { buf->data = (unsigned char *) YA_REALLOC(buf->alloc, buf->data, need); buf->len = need; } } yajl_buf yajl_buf_alloc(yajl_alloc_funcs * alloc) { yajl_buf b = YA_MALLOC(alloc, sizeof(struct yajl_buf_t)); memset((void *) b, 0, sizeof(struct yajl_buf_t)); b->alloc = alloc; return b; } void yajl_buf_free(yajl_buf buf) { assert(buf != NULL); if (buf->data) YA_FREE(buf->alloc, buf->data); YA_FREE(buf->alloc, buf); } void yajl_buf_append(yajl_buf buf, const void * data, size_t len) { yajl_buf_ensure_available(buf, len); if (len > 0) { assert(data != NULL); memcpy(buf->data + buf->used, data, len); buf->used += len; buf->data[buf->used] = 0; } } void yajl_buf_clear(yajl_buf buf) { buf->used = 0; if (buf->data) buf->data[buf->used] = 0; } const unsigned char * yajl_buf_data(yajl_buf buf) { return buf->data; } size_t yajl_buf_len(yajl_buf buf) { return buf->used; } void yajl_buf_truncate(yajl_buf buf, size_t len) { assert(len <= buf->used); buf->used = len; } mongodb-1.1.5/src/libbson/src/yajl/yajl_buf.h0000664000175000017500000000350512673034026020722 0ustar jmikolajmikola/* * Copyright (c) 2007-2011, Lloyd Hilaiel * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef __YAJL_BUF_H__ #define __YAJL_BUF_H__ #include "yajl_common.h" #include "yajl_alloc.h" /* * Implementation/performance notes. If this were moved to a header * only implementation using #define's where possible we might be * able to sqeeze a little performance out of the guy by killing function * call overhead. YMMV. */ /** * yajl_buf is a buffer with exponential growth. the buffer ensures that * you are always null padded. */ typedef struct yajl_buf_t * yajl_buf; /* allocate a new buffer */ yajl_buf yajl_buf_alloc(yajl_alloc_funcs * alloc); /* free the buffer */ void yajl_buf_free(yajl_buf buf); /* append a number of bytes to the buffer */ void yajl_buf_append(yajl_buf buf, const void * data, size_t len); /* empty the buffer */ void yajl_buf_clear(yajl_buf buf); /* get a pointer to the beginning of the buffer */ const unsigned char * yajl_buf_data(yajl_buf buf); /* get the length of the buffer */ size_t yajl_buf_len(yajl_buf buf); /* truncate the buffer */ void yajl_buf_truncate(yajl_buf buf, size_t len); #endif mongodb-1.1.5/src/libbson/src/yajl/yajl_bytestack.h0000664000175000017500000000451512673034026022141 0ustar jmikolajmikola/* * Copyright (c) 2007-2011, Lloyd Hilaiel * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* * A header only implementation of a simple stack of bytes, used in YAJL * to maintain parse state. */ #ifndef __YAJL_BYTESTACK_H__ #define __YAJL_BYTESTACK_H__ #include "yajl_common.h" #define YAJL_BS_INC 128 typedef struct yajl_bytestack_t { unsigned char * stack; size_t size; size_t used; yajl_alloc_funcs * yaf; } yajl_bytestack; /* initialize a bytestack */ #define yajl_bs_init(obs, _yaf) { \ (obs).stack = NULL; \ (obs).size = 0; \ (obs).used = 0; \ (obs).yaf = (_yaf); \ } \ /* initialize a bytestack */ #define yajl_bs_free(obs) \ if ((obs).stack) (obs).yaf->free((obs).yaf->ctx, (obs).stack); #define yajl_bs_current(obs) \ (assert((obs).used > 0), (obs).stack[(obs).used - 1]) #define yajl_bs_push(obs, byte) { \ if (((obs).size - (obs).used) == 0) { \ (obs).size += YAJL_BS_INC; \ (obs).stack = (obs).yaf->realloc((obs).yaf->ctx,\ (void *) (obs).stack, (obs).size);\ } \ (obs).stack[((obs).used)++] = (byte); \ } /* removes the top item of the stack, returns nothing */ #define yajl_bs_pop(obs) { ((obs).used)--; } #define yajl_bs_set(obs, byte) \ (obs).stack[((obs).used) - 1] = (byte); #endif mongodb-1.1.5/src/libbson/src/yajl/yajl_common.h0000664000175000017500000000502712673034026021437 0ustar jmikolajmikola/* * Copyright (c) 2007-2011, Lloyd Hilaiel * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef __YAJL_COMMON_H__ #define __YAJL_COMMON_H__ #include #ifdef __cplusplus extern "C" { #endif #define YAJL_MAX_DEPTH 128 /* msft dll export gunk. To build a DLL on windows, you * must define WIN32, YAJL_SHARED, and YAJL_BUILD. To use a shared * DLL, you must define YAJL_SHARED and WIN32 */ #if (defined(_WIN32) || defined(WIN32)) && defined(YAJL_SHARED) # ifdef YAJL_BUILD # define YAJL_API __declspec(dllexport) # else # define YAJL_API __declspec(dllimport) # endif #else # if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 303 # define YAJL_API __attribute__ ((visibility("default"))) # else # define YAJL_API # endif #endif /** pointer to a malloc function, supporting client overriding memory * allocation routines */ typedef void * (*yajl_malloc_func)(void *ctx, size_t sz); /** pointer to a free function, supporting client overriding memory * allocation routines */ typedef void (*yajl_free_func)(void *ctx, void * ptr); /** pointer to a realloc function which can resize an allocation. */ typedef void * (*yajl_realloc_func)(void *ctx, void * ptr, size_t sz); /** A structure which can be passed to yajl_*_alloc routines to allow the * client to specify memory allocation functions to be used. */ typedef struct { /** pointer to a function that can allocate uninitialized memory */ yajl_malloc_func malloc; /** pointer to a function that can resize memory allocations */ yajl_realloc_func realloc; /** pointer to a function that can free memory allocated using * reallocFunction or mallocFunction */ yajl_free_func free; /** a context pointer that will be passed to above allocation routines */ void * ctx; } yajl_alloc_funcs; #ifdef __cplusplus } #endif #endif mongodb-1.1.5/src/libbson/src/yajl/yajl_encode.c0000664000175000017500000001615612673034026021404 0ustar jmikolajmikola/* * Copyright (c) 2007-2011, Lloyd Hilaiel * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "yajl_encode.h" #include #include #include #include static void CharToHex(unsigned char c, char * hexBuf) { const char * hexchar = "0123456789ABCDEF"; hexBuf[0] = hexchar[c >> 4]; hexBuf[1] = hexchar[c & 0x0F]; } void yajl_string_encode(const yajl_print_t print, void * ctx, const unsigned char * str, size_t len, int escape_solidus) { size_t beg = 0; size_t end = 0; char hexBuf[7]; hexBuf[0] = '\\'; hexBuf[1] = 'u'; hexBuf[2] = '0'; hexBuf[3] = '0'; hexBuf[6] = 0; while (end < len) { const char * escaped = NULL; switch (str[end]) { case '\r': escaped = "\\r"; break; case '\n': escaped = "\\n"; break; case '\\': escaped = "\\\\"; break; /* it is not required to escape a solidus in JSON: * read sec. 2.5: http://www.ietf.org/rfc/rfc4627.txt * specifically, this production from the grammar: * unescaped = %x20-21 / %x23-5B / %x5D-10FFFF */ case '/': if (escape_solidus) escaped = "\\/"; break; case '"': escaped = "\\\""; break; case '\f': escaped = "\\f"; break; case '\b': escaped = "\\b"; break; case '\t': escaped = "\\t"; break; default: if ((unsigned char) str[end] < 32) { CharToHex(str[end], hexBuf + 4); escaped = hexBuf; } break; } if (escaped != NULL) { print(ctx, (const char *) (str + beg), end - beg); print(ctx, escaped, (unsigned int)strlen(escaped)); beg = ++end; } else { ++end; } } print(ctx, (const char *) (str + beg), end - beg); } static void hexToDigit(unsigned int * val, const unsigned char * hex) { unsigned int i; for (i=0;i<4;i++) { unsigned char c = hex[i]; if (c >= 'A') c = (c & ~0x20) - 7; c -= '0'; assert(!(c & 0xF0)); *val = (*val << 4) | c; } } static void Utf32toUtf8(unsigned int codepoint, char * utf8Buf) { if (codepoint < 0x80) { utf8Buf[0] = (char) codepoint; utf8Buf[1] = 0; } else if (codepoint < 0x0800) { utf8Buf[0] = (char) ((codepoint >> 6) | 0xC0); utf8Buf[1] = (char) ((codepoint & 0x3F) | 0x80); utf8Buf[2] = 0; } else if (codepoint < 0x10000) { utf8Buf[0] = (char) ((codepoint >> 12) | 0xE0); utf8Buf[1] = (char) (((codepoint >> 6) & 0x3F) | 0x80); utf8Buf[2] = (char) ((codepoint & 0x3F) | 0x80); utf8Buf[3] = 0; } else if (codepoint < 0x200000) { utf8Buf[0] =(char)((codepoint >> 18) | 0xF0); utf8Buf[1] =(char)(((codepoint >> 12) & 0x3F) | 0x80); utf8Buf[2] =(char)(((codepoint >> 6) & 0x3F) | 0x80); utf8Buf[3] =(char)((codepoint & 0x3F) | 0x80); utf8Buf[4] = 0; } else { utf8Buf[0] = '?'; utf8Buf[1] = 0; } } void yajl_string_decode(yajl_buf buf, const unsigned char * str, size_t len) { size_t beg = 0; size_t end = 0; while (end < len) { if (str[end] == '\\') { char utf8Buf[5]; const char * unescaped = "?"; yajl_buf_append(buf, str + beg, end - beg); switch (str[++end]) { case 'r': unescaped = "\r"; break; case 'n': unescaped = "\n"; break; case '\\': unescaped = "\\"; break; case '/': unescaped = "/"; break; case '"': unescaped = "\""; break; case 'f': unescaped = "\f"; break; case 'b': unescaped = "\b"; break; case 't': unescaped = "\t"; break; case 'u': { unsigned int codepoint = 0; hexToDigit(&codepoint, str + ++end); end+=3; /* check if this is a surrogate */ if ((codepoint & 0xFC00) == 0xD800) { end++; if (str[end] == '\\' && str[end + 1] == 'u') { unsigned int surrogate = 0; hexToDigit(&surrogate, str + end + 2); codepoint = (((codepoint & 0x3F) << 10) | ((((codepoint >> 6) & 0xF) + 1) << 16) | (surrogate & 0x3FF)); end += 5; } else { unescaped = "?"; break; } } Utf32toUtf8(codepoint, utf8Buf); unescaped = utf8Buf; if (codepoint == 0) { yajl_buf_append(buf, unescaped, 1); beg = ++end; continue; } break; } default: assert("this should never happen" == NULL); } yajl_buf_append(buf, unescaped, (unsigned int)strlen(unescaped)); beg = ++end; } else { end++; } } yajl_buf_append(buf, str + beg, end - beg); } #define ADV_PTR s++; if (!(len--)) return 0; int yajl_string_validate_utf8(const unsigned char * s, size_t len) { if (!len) return 1; if (!s) return 0; while (len--) { /* single byte */ if (*s <= 0x7f) { /* noop */ } /* two byte */ else if ((*s >> 5) == 0x6) { ADV_PTR; if (!((*s >> 6) == 0x2)) return 0; } /* three byte */ else if ((*s >> 4) == 0x0e) { ADV_PTR; if (!((*s >> 6) == 0x2)) return 0; ADV_PTR; if (!((*s >> 6) == 0x2)) return 0; } /* four byte */ else if ((*s >> 3) == 0x1e) { ADV_PTR; if (!((*s >> 6) == 0x2)) return 0; ADV_PTR; if (!((*s >> 6) == 0x2)) return 0; ADV_PTR; if (!((*s >> 6) == 0x2)) return 0; } else { return 0; } s++; } return 1; } mongodb-1.1.5/src/libbson/src/yajl/yajl_encode.h0000664000175000017500000000243212673034026021401 0ustar jmikolajmikola/* * Copyright (c) 2007-2011, Lloyd Hilaiel * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef __YAJL_ENCODE_H__ #define __YAJL_ENCODE_H__ #include "yajl_buf.h" #include "yajl_gen.h" void yajl_string_encode(const yajl_print_t printer, void * ctx, const unsigned char * str, size_t length, int escape_solidus); void yajl_string_decode(yajl_buf buf, const unsigned char * str, size_t length); int yajl_string_validate_utf8(const unsigned char * s, size_t len); #endif mongodb-1.1.5/src/libbson/src/yajl/yajl_gen.c0000664000175000017500000002526512673034026020721 0ustar jmikolajmikola/* * Copyright (c) 2007-2011, Lloyd Hilaiel * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "yajl_gen.h" #include "yajl_buf.h" #include "yajl_encode.h" #include #include #include #include #include typedef enum { yajl_gen_start, yajl_gen_map_start, yajl_gen_map_key, yajl_gen_map_val, yajl_gen_array_start, yajl_gen_in_array, yajl_gen_complete, yajl_gen_error } yajl_gen_state; struct yajl_gen_t { unsigned int flags; unsigned int depth; const char * indentString; yajl_gen_state state[YAJL_MAX_DEPTH]; yajl_print_t print; void * ctx; /* yajl_buf */ /* memory allocation routines */ yajl_alloc_funcs alloc; }; int yajl_gen_config(yajl_gen g, yajl_gen_option opt, ...) { int rv = 1; va_list ap; va_start(ap, opt); switch(opt) { case yajl_gen_beautify: case yajl_gen_validate_utf8: case yajl_gen_escape_solidus: if (va_arg(ap, int)) g->flags |= opt; else g->flags &= ~opt; break; case yajl_gen_indent_string: { const char *indent = va_arg(ap, const char *); g->indentString = indent; for (; *indent; indent++) { if (*indent != '\n' && *indent != '\v' && *indent != '\f' && *indent != '\t' && *indent != '\r' && *indent != ' ') { g->indentString = NULL; rv = 0; } } break; } case yajl_gen_print_callback: yajl_buf_free(g->ctx); g->print = va_arg(ap, const yajl_print_t); g->ctx = va_arg(ap, void *); break; default: rv = 0; } va_end(ap); return rv; } yajl_gen yajl_gen_alloc(const yajl_alloc_funcs * afs) { yajl_gen g = NULL; yajl_alloc_funcs afsBuffer; /* first order of business is to set up memory allocation routines */ if (afs != NULL) { if (afs->malloc == NULL || afs->realloc == NULL || afs->free == NULL) { return NULL; } } else { yajl_set_default_alloc_funcs(&afsBuffer); afs = &afsBuffer; } g = (yajl_gen) YA_MALLOC(afs, sizeof(struct yajl_gen_t)); if (!g) return NULL; memset((void *) g, 0, sizeof(struct yajl_gen_t)); /* copy in pointers to allocation routines */ memcpy((void *) &(g->alloc), (void *) afs, sizeof(yajl_alloc_funcs)); g->print = (yajl_print_t)&yajl_buf_append; g->ctx = yajl_buf_alloc(&(g->alloc)); g->indentString = " "; return g; } void yajl_gen_free(yajl_gen g) { if (g->print == (yajl_print_t)&yajl_buf_append) yajl_buf_free((yajl_buf)g->ctx); YA_FREE(&(g->alloc), g); } #define INSERT_SEP \ if (g->state[g->depth] == yajl_gen_map_key || \ g->state[g->depth] == yajl_gen_in_array) { \ g->print(g->ctx, ",", 1); \ if ((g->flags & yajl_gen_beautify)) g->print(g->ctx, "\n", 1); \ } else if (g->state[g->depth] == yajl_gen_map_val) { \ g->print(g->ctx, ":", 1); \ if ((g->flags & yajl_gen_beautify)) g->print(g->ctx, " ", 1); \ } #define INSERT_WHITESPACE \ if ((g->flags & yajl_gen_beautify)) { \ if (g->state[g->depth] != yajl_gen_map_val) { \ unsigned int _i; \ for (_i=0;_idepth;_i++) \ g->print(g->ctx, \ g->indentString, \ (unsigned int)strlen(g->indentString)); \ } \ } #define ENSURE_NOT_KEY \ if (g->state[g->depth] == yajl_gen_map_key || \ g->state[g->depth] == yajl_gen_map_start) { \ return yajl_gen_keys_must_be_strings; \ } \ /* check that we're not complete, or in error state. in a valid state * to be generating */ #define ENSURE_VALID_STATE \ if (g->state[g->depth] == yajl_gen_error) { \ return yajl_gen_in_error_state;\ } else if (g->state[g->depth] == yajl_gen_complete) { \ return yajl_gen_generation_complete; \ } #define INCREMENT_DEPTH \ if (++(g->depth) >= YAJL_MAX_DEPTH) return yajl_max_depth_exceeded; #define DECREMENT_DEPTH \ if (--(g->depth) >= YAJL_MAX_DEPTH) return yajl_gen_invalid_string; #define APPENDED_ATOM \ switch (g->state[g->depth]) { \ case yajl_gen_start: \ g->state[g->depth] = yajl_gen_complete; \ break; \ case yajl_gen_map_start: \ case yajl_gen_map_key: \ g->state[g->depth] = yajl_gen_map_val; \ break; \ case yajl_gen_array_start: \ g->state[g->depth] = yajl_gen_in_array; \ break; \ case yajl_gen_map_val: \ g->state[g->depth] = yajl_gen_map_key; \ break; \ default: \ break; \ } \ #define FINAL_NEWLINE \ if ((g->flags & yajl_gen_beautify) && g->state[g->depth] == yajl_gen_complete) \ g->print(g->ctx, "\n", 1); yajl_gen_status yajl_gen_integer(yajl_gen g, long long int number) { char i[32]; ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE; sprintf(i, "%lld", number); g->print(g->ctx, i, (unsigned int)strlen(i)); APPENDED_ATOM; FINAL_NEWLINE; return yajl_gen_status_ok; } #if defined(_WIN32) || defined(WIN32) # include # ifndef isnan # define isnan _isnan # endif # ifndef isinf # define isinf !_finite # endif #endif #if defined(__sun) && defined(__GNUC__) && __GNUC__ < 4 # define isinf !finite #endif yajl_gen_status yajl_gen_double(yajl_gen g, double number) { char i[32]; ENSURE_VALID_STATE; ENSURE_NOT_KEY; if (isnan(number) || isinf(number)) return yajl_gen_invalid_number; INSERT_SEP; INSERT_WHITESPACE; sprintf(i, "%.20g", number); if (strspn(i, "0123456789-") == strlen(i)) { strcat(i, ".0"); } g->print(g->ctx, i, (unsigned int)strlen(i)); APPENDED_ATOM; FINAL_NEWLINE; return yajl_gen_status_ok; } yajl_gen_status yajl_gen_number(yajl_gen g, const char * s, size_t l) { ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE; g->print(g->ctx, s, l); APPENDED_ATOM; FINAL_NEWLINE; return yajl_gen_status_ok; } yajl_gen_status yajl_gen_string(yajl_gen g, const unsigned char * str, size_t len) { // if validation is enabled, check that the string is valid utf8 // XXX: This checking could be done a little faster, in the same pass as // the string encoding if (g->flags & yajl_gen_validate_utf8) { if (!yajl_string_validate_utf8(str, len)) { return yajl_gen_invalid_string; } } ENSURE_VALID_STATE; INSERT_SEP; INSERT_WHITESPACE; g->print(g->ctx, "\"", 1); yajl_string_encode(g->print, g->ctx, str, len, g->flags & yajl_gen_escape_solidus); g->print(g->ctx, "\"", 1); APPENDED_ATOM; FINAL_NEWLINE; return yajl_gen_status_ok; } yajl_gen_status yajl_gen_null(yajl_gen g) { ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE; g->print(g->ctx, "null", strlen("null")); APPENDED_ATOM; FINAL_NEWLINE; return yajl_gen_status_ok; } yajl_gen_status yajl_gen_bool(yajl_gen g, int boolean) { const char * val = boolean ? "true" : "false"; ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE; g->print(g->ctx, val, (unsigned int)strlen(val)); APPENDED_ATOM; FINAL_NEWLINE; return yajl_gen_status_ok; } yajl_gen_status yajl_gen_map_open(yajl_gen g) { ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE; INCREMENT_DEPTH; g->state[g->depth] = yajl_gen_map_start; g->print(g->ctx, "{", 1); if ((g->flags & yajl_gen_beautify)) g->print(g->ctx, "\n", 1); FINAL_NEWLINE; return yajl_gen_status_ok; } yajl_gen_status yajl_gen_map_close(yajl_gen g) { ENSURE_VALID_STATE; DECREMENT_DEPTH; if ((g->flags & yajl_gen_beautify)) g->print(g->ctx, "\n", 1); APPENDED_ATOM; INSERT_WHITESPACE; g->print(g->ctx, "}", 1); FINAL_NEWLINE; return yajl_gen_status_ok; } yajl_gen_status yajl_gen_array_open(yajl_gen g) { ENSURE_VALID_STATE; ENSURE_NOT_KEY; INSERT_SEP; INSERT_WHITESPACE; INCREMENT_DEPTH; g->state[g->depth] = yajl_gen_array_start; g->print(g->ctx, "[", 1); if ((g->flags & yajl_gen_beautify)) g->print(g->ctx, "\n", 1); FINAL_NEWLINE; return yajl_gen_status_ok; } yajl_gen_status yajl_gen_array_close(yajl_gen g) { ENSURE_VALID_STATE; DECREMENT_DEPTH; if ((g->flags & yajl_gen_beautify)) g->print(g->ctx, "\n", 1); APPENDED_ATOM; INSERT_WHITESPACE; g->print(g->ctx, "]", 1); FINAL_NEWLINE; return yajl_gen_status_ok; } yajl_gen_status yajl_gen_get_buf(yajl_gen g, const unsigned char ** buf, size_t * len) { if (g->print != (yajl_print_t)&yajl_buf_append) return yajl_gen_no_buf; *buf = yajl_buf_data((yajl_buf)g->ctx); *len = yajl_buf_len((yajl_buf)g->ctx); return yajl_gen_status_ok; } void yajl_gen_clear(yajl_gen g) { if (g->print == (yajl_print_t)&yajl_buf_append) yajl_buf_clear((yajl_buf)g->ctx); } mongodb-1.1.5/src/libbson/src/yajl/yajl_gen.h0000664000175000017500000001476112673034026020725 0ustar jmikolajmikola/* * Copyright (c) 2007-2011, Lloyd Hilaiel * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /** * \file yajl_gen.h * Interface to YAJL's JSON generation facilities. */ #include #ifndef __YAJL_GEN_H__ #define __YAJL_GEN_H__ #include #ifdef __cplusplus extern "C" { #endif /** generator status codes */ typedef enum { /** no error */ yajl_gen_status_ok = 0, /** at a point where a map key is generated, a function other than * yajl_gen_string was called */ yajl_gen_keys_must_be_strings, /** YAJL's maximum generation depth was exceeded. see * YAJL_MAX_DEPTH */ yajl_max_depth_exceeded, /** A generator function (yajl_gen_XXX) was called while in an error * state */ yajl_gen_in_error_state, /** A complete JSON document has been generated */ yajl_gen_generation_complete, /** yajl_gen_double was passed an invalid floating point value * (infinity or NaN). */ yajl_gen_invalid_number, /** A print callback was passed in, so there is no internal * buffer to get from */ yajl_gen_no_buf, /** returned from yajl_gen_string() when the yajl_gen_validate_utf8 * option is enabled and an invalid was passed by client code. */ yajl_gen_invalid_string } yajl_gen_status; /** an opaque handle to a generator */ typedef struct yajl_gen_t * yajl_gen; /** a callback used for "printing" the results. */ typedef void (*yajl_print_t)(void * ctx, const char * str, size_t len); /** configuration parameters for the parser, these may be passed to * yajl_gen_config() along with option specific argument(s). In general, * all configuration parameters default to *off*. */ typedef enum { /** generate indented (beautiful) output */ yajl_gen_beautify = 0x01, /** * Set an indent string which is used when yajl_gen_beautify * is enabled. Maybe something like \\t or some number of * spaces. The default is four spaces ' '. */ yajl_gen_indent_string = 0x02, /** * Set a function and context argument that should be used to * output generated json. the function should conform to the * yajl_print_t prototype while the context argument is a * void * of your choosing. * * example: * yajl_gen_config(g, yajl_gen_print_callback, myFunc, myVoidPtr); */ yajl_gen_print_callback = 0x04, /** * Normally the generator does not validate that strings you * pass to it via yajl_gen_string() are valid UTF8. Enabling * this option will cause it to do so. */ yajl_gen_validate_utf8 = 0x08, /** * the forward solidus (slash or '/' in human) is not required to be * escaped in json text. By default, YAJL will not escape it in the * iterest of saving bytes. Setting this flag will cause YAJL to * always escape '/' in generated JSON strings. */ yajl_gen_escape_solidus = 0x10 } yajl_gen_option; /** allow the modification of generator options subsequent to handle * allocation (via yajl_alloc) * \returns zero in case of errors, non-zero otherwise */ YAJL_API int yajl_gen_config(yajl_gen g, yajl_gen_option opt, ...); /** allocate a generator handle * \param allocFuncs an optional pointer to a structure which allows * the client to overide the memory allocation * used by yajl. May be NULL, in which case * malloc/free/realloc will be used. * * \returns an allocated handle on success, NULL on failure (bad params) */ YAJL_API yajl_gen yajl_gen_alloc(const yajl_alloc_funcs * allocFuncs); /** free a generator handle */ YAJL_API void yajl_gen_free(yajl_gen handle); YAJL_API yajl_gen_status yajl_gen_integer(yajl_gen hand, long long int number); /** generate a floating point number. number may not be infinity or * NaN, as these have no representation in JSON. In these cases the * generator will return 'yajl_gen_invalid_number' */ YAJL_API yajl_gen_status yajl_gen_double(yajl_gen hand, double number); YAJL_API yajl_gen_status yajl_gen_number(yajl_gen hand, const char * num, size_t len); YAJL_API yajl_gen_status yajl_gen_string(yajl_gen hand, const unsigned char * str, size_t len); YAJL_API yajl_gen_status yajl_gen_null(yajl_gen hand); YAJL_API yajl_gen_status yajl_gen_bool(yajl_gen hand, int boolean); YAJL_API yajl_gen_status yajl_gen_map_open(yajl_gen hand); YAJL_API yajl_gen_status yajl_gen_map_close(yajl_gen hand); YAJL_API yajl_gen_status yajl_gen_array_open(yajl_gen hand); YAJL_API yajl_gen_status yajl_gen_array_close(yajl_gen hand); /** access the null terminated generator buffer. If incrementally * outputing JSON, one should call yajl_gen_clear to clear the * buffer. This allows stream generation. */ YAJL_API yajl_gen_status yajl_gen_get_buf(yajl_gen hand, const unsigned char ** buf, size_t * len); /** clear yajl's output buffer, but maintain all internal generation * state. This function will not "reset" the generator state, and is * intended to enable incremental JSON outputing. */ YAJL_API void yajl_gen_clear(yajl_gen hand); #ifdef __cplusplus } #endif #endif mongodb-1.1.5/src/libbson/src/yajl/yajl_lex.c0000664000175000017500000006351312673034026020736 0ustar jmikolajmikola/* * Copyright (c) 2007-2011, Lloyd Hilaiel * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "yajl_lex.h" #include "yajl_buf.h" #include #include #include #include #ifdef YAJL_LEXER_DEBUG static const char * tokToStr(yajl_tok tok) { switch (tok) { case yajl_tok_bool: return "bool"; case yajl_tok_colon: return "colon"; case yajl_tok_comma: return "comma"; case yajl_tok_eof: return "eof"; case yajl_tok_error: return "error"; case yajl_tok_left_brace: return "brace"; case yajl_tok_left_bracket: return "bracket"; case yajl_tok_null: return "null"; case yajl_tok_integer: return "integer"; case yajl_tok_double: return "double"; case yajl_tok_right_brace: return "brace"; case yajl_tok_right_bracket: return "bracket"; case yajl_tok_string: return "string"; case yajl_tok_string_with_escapes: return "string_with_escapes"; } return "unknown"; } #endif /* Impact of the stream parsing feature on the lexer: * * YAJL support stream parsing. That is, the ability to parse the first * bits of a chunk of JSON before the last bits are available (still on * the network or disk). This makes the lexer more complex. The * responsibility of the lexer is to handle transparently the case where * a chunk boundary falls in the middle of a token. This is * accomplished is via a buffer and a character reading abstraction. * * Overview of implementation * * When we lex to end of input string before end of token is hit, we * copy all of the input text composing the token into our lexBuf. * * Every time we read a character, we do so through the readChar function. * readChar's responsibility is to handle pulling all chars from the buffer * before pulling chars from input text */ struct yajl_lexer_t { /* the overal line and char offset into the data */ size_t lineOff; size_t charOff; /* error */ yajl_lex_error error; /* a input buffer to handle the case where a token is spread over * multiple chunks */ yajl_buf buf; /* in the case where we have data in the lexBuf, bufOff holds * the current offset into the lexBuf. */ size_t bufOff; /* are we using the lex buf? */ unsigned int bufInUse; /* shall we allow comments? */ unsigned int allowComments; /* shall we validate utf8 inside strings? */ unsigned int validateUTF8; yajl_alloc_funcs * alloc; }; #define readChar(lxr, txt, off) \ (((lxr)->bufInUse && yajl_buf_len((lxr)->buf) && lxr->bufOff < yajl_buf_len((lxr)->buf)) ? \ (*((const unsigned char *) yajl_buf_data((lxr)->buf) + ((lxr)->bufOff)++)) : \ ((txt)[(*(off))++])) #define unreadChar(lxr, off) ((*(off) > 0) ? (*(off))-- : ((lxr)->bufOff--)) yajl_lexer yajl_lex_alloc(yajl_alloc_funcs * alloc, unsigned int allowComments, unsigned int validateUTF8) { yajl_lexer lxr = (yajl_lexer) YA_MALLOC(alloc, sizeof(struct yajl_lexer_t)); memset((void *) lxr, 0, sizeof(struct yajl_lexer_t)); lxr->buf = yajl_buf_alloc(alloc); lxr->allowComments = allowComments; lxr->validateUTF8 = validateUTF8; lxr->alloc = alloc; return lxr; } void yajl_lex_free(yajl_lexer lxr) { yajl_buf_free(lxr->buf); YA_FREE(lxr->alloc, lxr); return; } /* a lookup table which lets us quickly determine three things: * VEC - valid escaped control char * note. the solidus '/' may be escaped or not. * IJC - invalid json char * VHC - valid hex char * NFP - needs further processing (from a string scanning perspective) * NUC - needs utf8 checking when enabled (from a string scanning perspective) */ #define VEC 0x01 #define IJC 0x02 #define VHC 0x04 #define NFP 0x08 #define NUC 0x10 static const char charLookupTable[256] = { /*00*/ IJC , IJC , IJC , IJC , IJC , IJC , IJC , IJC , /*08*/ IJC , IJC , IJC , IJC , IJC , IJC , IJC , IJC , /*10*/ IJC , IJC , IJC , IJC , IJC , IJC , IJC , IJC , /*18*/ IJC , IJC , IJC , IJC , IJC , IJC , IJC , IJC , /*20*/ 0 , 0 , NFP|VEC|IJC, 0 , 0 , 0 , 0 , 0 , /*28*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , VEC , /*30*/ VHC , VHC , VHC , VHC , VHC , VHC , VHC , VHC , /*38*/ VHC , VHC , 0 , 0 , 0 , 0 , 0 , 0 , /*40*/ 0 , VHC , VHC , VHC , VHC , VHC , VHC , 0 , /*48*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , /*50*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , /*58*/ 0 , 0 , 0 , 0 , NFP|VEC|IJC, 0 , 0 , 0 , /*60*/ 0 , VHC , VEC|VHC, VHC , VHC , VHC , VEC|VHC, 0 , /*68*/ 0 , 0 , 0 , 0 , 0 , 0 , VEC , 0 , /*70*/ 0 , 0 , VEC , 0 , VEC , 0 , 0 , 0 , /*78*/ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC , NUC }; /** process a variable length utf8 encoded codepoint. * * returns: * yajl_tok_string - if valid utf8 char was parsed and offset was * advanced * yajl_tok_eof - if end of input was hit before validation could * complete * yajl_tok_error - if invalid utf8 was encountered * * NOTE: on error the offset will point to the first char of the * invalid utf8 */ #define UTF8_CHECK_EOF if (*offset >= jsonTextLen) { return yajl_tok_eof; } static yajl_tok yajl_lex_utf8_char(yajl_lexer lexer, const unsigned char * jsonText, size_t jsonTextLen, size_t * offset, unsigned char curChar) { if (curChar <= 0x7f) { /* single byte */ return yajl_tok_string; } else if ((curChar >> 5) == 0x6) { /* two byte */ UTF8_CHECK_EOF; curChar = readChar(lexer, jsonText, offset); if ((curChar >> 6) == 0x2) return yajl_tok_string; } else if ((curChar >> 4) == 0x0e) { /* three byte */ UTF8_CHECK_EOF; curChar = readChar(lexer, jsonText, offset); if ((curChar >> 6) == 0x2) { UTF8_CHECK_EOF; curChar = readChar(lexer, jsonText, offset); if ((curChar >> 6) == 0x2) return yajl_tok_string; } } else if ((curChar >> 3) == 0x1e) { /* four byte */ UTF8_CHECK_EOF; curChar = readChar(lexer, jsonText, offset); if ((curChar >> 6) == 0x2) { UTF8_CHECK_EOF; curChar = readChar(lexer, jsonText, offset); if ((curChar >> 6) == 0x2) { UTF8_CHECK_EOF; curChar = readChar(lexer, jsonText, offset); if ((curChar >> 6) == 0x2) return yajl_tok_string; } } } return yajl_tok_error; } /* lex a string. input is the lexer, pointer to beginning of * json text, and start of string (offset). * a token is returned which has the following meanings: * yajl_tok_string: lex of string was successful. offset points to * terminating '"'. * yajl_tok_eof: end of text was encountered before we could complete * the lex. * yajl_tok_error: embedded in the string were unallowable chars. offset * points to the offending char */ #define STR_CHECK_EOF \ if (*offset >= jsonTextLen) { \ tok = yajl_tok_eof; \ goto finish_string_lex; \ } /** scan a string for interesting characters that might need further * review. return the number of chars that are uninteresting and can * be skipped. * (lth) hi world, any thoughts on how to make this routine faster? */ static size_t yajl_string_scan(const unsigned char * buf, size_t len, int utf8check) { unsigned char mask = IJC|NFP|(utf8check ? NUC : 0); size_t skip = 0; while (skip < len && !(charLookupTable[*buf] & mask)) { skip++; buf++; } return skip; } static yajl_tok yajl_lex_string(yajl_lexer lexer, const unsigned char * jsonText, size_t jsonTextLen, size_t * offset) { yajl_tok tok = yajl_tok_error; int hasEscapes = 0; for (;;) { unsigned char curChar; /* now jump into a faster scanning routine to skip as much * of the buffers as possible */ { const unsigned char * p; size_t len; if ((lexer->bufInUse && yajl_buf_len(lexer->buf) && lexer->bufOff < yajl_buf_len(lexer->buf))) { p = ((const unsigned char *) yajl_buf_data(lexer->buf) + (lexer->bufOff)); len = yajl_buf_len(lexer->buf) - lexer->bufOff; lexer->bufOff += yajl_string_scan(p, len, lexer->validateUTF8); } else if (*offset < jsonTextLen) { p = jsonText + *offset; len = jsonTextLen - *offset; *offset += yajl_string_scan(p, len, lexer->validateUTF8); } } STR_CHECK_EOF; curChar = readChar(lexer, jsonText, offset); /* quote terminates */ if (curChar == '"') { tok = yajl_tok_string; break; } /* backslash escapes a set of control chars, */ else if (curChar == '\\') { hasEscapes = 1; STR_CHECK_EOF; /* special case \u */ curChar = readChar(lexer, jsonText, offset); if (curChar == 'u') { unsigned int i = 0; for (i=0;i<4;i++) { STR_CHECK_EOF; curChar = readChar(lexer, jsonText, offset); if (!(charLookupTable[curChar] & VHC)) { /* back up to offending char */ unreadChar(lexer, offset); lexer->error = yajl_lex_string_invalid_hex_char; goto finish_string_lex; } } } else if (!(charLookupTable[curChar] & VEC)) { /* back up to offending char */ unreadChar(lexer, offset); lexer->error = yajl_lex_string_invalid_escaped_char; goto finish_string_lex; } } /* when not validating UTF8 it's a simple table lookup to determine * if the present character is invalid */ else if(charLookupTable[curChar] & IJC) { /* back up to offending char */ unreadChar(lexer, offset); lexer->error = yajl_lex_string_invalid_json_char; goto finish_string_lex; } /* when in validate UTF8 mode we need to do some extra work */ else if (lexer->validateUTF8) { yajl_tok t = yajl_lex_utf8_char(lexer, jsonText, jsonTextLen, offset, curChar); if (t == yajl_tok_eof) { tok = yajl_tok_eof; goto finish_string_lex; } else if (t == yajl_tok_error) { lexer->error = yajl_lex_string_invalid_utf8; goto finish_string_lex; } } /* accept it, and move on */ } finish_string_lex: /* tell our buddy, the parser, wether he needs to process this string * again */ if (hasEscapes && tok == yajl_tok_string) { tok = yajl_tok_string_with_escapes; } return tok; } #define RETURN_IF_EOF if (*offset >= jsonTextLen) return yajl_tok_eof; static yajl_tok yajl_lex_number(yajl_lexer lexer, const unsigned char * jsonText, size_t jsonTextLen, size_t * offset) { /** XXX: numbers are the only entities in json that we must lex * _beyond_ in order to know that they are complete. There * is an ambiguous case for integers at EOF. */ unsigned char c; yajl_tok tok = yajl_tok_integer; RETURN_IF_EOF; c = readChar(lexer, jsonText, offset); /* optional leading minus */ if (c == '-') { RETURN_IF_EOF; c = readChar(lexer, jsonText, offset); } /* a single zero, or a series of integers */ if (c == '0') { RETURN_IF_EOF; c = readChar(lexer, jsonText, offset); } else if (c >= '1' && c <= '9') { do { RETURN_IF_EOF; c = readChar(lexer, jsonText, offset); } while (c >= '0' && c <= '9'); } else { unreadChar(lexer, offset); lexer->error = yajl_lex_missing_integer_after_minus; return yajl_tok_error; } /* optional fraction (indicates this is floating point) */ if (c == '.') { int numRd = 0; RETURN_IF_EOF; c = readChar(lexer, jsonText, offset); while (c >= '0' && c <= '9') { numRd++; RETURN_IF_EOF; c = readChar(lexer, jsonText, offset); } if (!numRd) { unreadChar(lexer, offset); lexer->error = yajl_lex_missing_integer_after_decimal; return yajl_tok_error; } tok = yajl_tok_double; } /* optional exponent (indicates this is floating point) */ if (c == 'e' || c == 'E') { RETURN_IF_EOF; c = readChar(lexer, jsonText, offset); /* optional sign */ if (c == '+' || c == '-') { RETURN_IF_EOF; c = readChar(lexer, jsonText, offset); } if (c >= '0' && c <= '9') { do { RETURN_IF_EOF; c = readChar(lexer, jsonText, offset); } while (c >= '0' && c <= '9'); } else { unreadChar(lexer, offset); lexer->error = yajl_lex_missing_integer_after_exponent; return yajl_tok_error; } tok = yajl_tok_double; } /* we always go "one too far" */ unreadChar(lexer, offset); return tok; } static yajl_tok yajl_lex_comment(yajl_lexer lexer, const unsigned char * jsonText, size_t jsonTextLen, size_t * offset) { unsigned char c; yajl_tok tok = yajl_tok_comment; RETURN_IF_EOF; c = readChar(lexer, jsonText, offset); /* either slash or star expected */ if (c == '/') { /* now we throw away until end of line */ do { RETURN_IF_EOF; c = readChar(lexer, jsonText, offset); } while (c != '\n'); } else if (c == '*') { /* now we throw away until end of comment */ for (;;) { RETURN_IF_EOF; c = readChar(lexer, jsonText, offset); if (c == '*') { RETURN_IF_EOF; c = readChar(lexer, jsonText, offset); if (c == '/') { break; } else { unreadChar(lexer, offset); } } } } else { lexer->error = yajl_lex_invalid_char; tok = yajl_tok_error; } return tok; } yajl_tok yajl_lex_lex(yajl_lexer lexer, const unsigned char * jsonText, size_t jsonTextLen, size_t * offset, const unsigned char ** outBuf, size_t * outLen) { yajl_tok tok = yajl_tok_error; unsigned char c; size_t startOffset = *offset; *outBuf = NULL; *outLen = 0; for (;;) { assert(*offset <= jsonTextLen); if (*offset >= jsonTextLen) { tok = yajl_tok_eof; goto lexed; } c = readChar(lexer, jsonText, offset); switch (c) { case '{': tok = yajl_tok_left_bracket; goto lexed; case '}': tok = yajl_tok_right_bracket; goto lexed; case '[': tok = yajl_tok_left_brace; goto lexed; case ']': tok = yajl_tok_right_brace; goto lexed; case ',': tok = yajl_tok_comma; goto lexed; case ':': tok = yajl_tok_colon; goto lexed; case '\t': case '\n': case '\v': case '\f': case '\r': case ' ': startOffset++; break; case 't': { const char * want = "rue"; do { if (*offset >= jsonTextLen) { tok = yajl_tok_eof; goto lexed; } c = readChar(lexer, jsonText, offset); if (c != *want) { unreadChar(lexer, offset); lexer->error = yajl_lex_invalid_string; tok = yajl_tok_error; goto lexed; } } while (*(++want)); tok = yajl_tok_bool; goto lexed; } case 'f': { const char * want = "alse"; do { if (*offset >= jsonTextLen) { tok = yajl_tok_eof; goto lexed; } c = readChar(lexer, jsonText, offset); if (c != *want) { unreadChar(lexer, offset); lexer->error = yajl_lex_invalid_string; tok = yajl_tok_error; goto lexed; } } while (*(++want)); tok = yajl_tok_bool; goto lexed; } case 'n': { const char * want = "ull"; do { if (*offset >= jsonTextLen) { tok = yajl_tok_eof; goto lexed; } c = readChar(lexer, jsonText, offset); if (c != *want) { unreadChar(lexer, offset); lexer->error = yajl_lex_invalid_string; tok = yajl_tok_error; goto lexed; } } while (*(++want)); tok = yajl_tok_null; goto lexed; } case '"': { tok = yajl_lex_string(lexer, (const unsigned char *) jsonText, jsonTextLen, offset); goto lexed; } case '-': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { /* integer parsing wants to start from the beginning */ unreadChar(lexer, offset); tok = yajl_lex_number(lexer, (const unsigned char *) jsonText, jsonTextLen, offset); goto lexed; } case '/': /* hey, look, a probable comment! If comments are disabled * it's an error. */ if (!lexer->allowComments) { unreadChar(lexer, offset); lexer->error = yajl_lex_unallowed_comment; tok = yajl_tok_error; goto lexed; } /* if comments are enabled, then we should try to lex * the thing. possible outcomes are * - successful lex (tok_comment, which means continue), * - malformed comment opening (slash not followed by * '*' or '/') (tok_error) * - eof hit. (tok_eof) */ tok = yajl_lex_comment(lexer, (const unsigned char *) jsonText, jsonTextLen, offset); if (tok == yajl_tok_comment) { /* "error" is silly, but that's the initial * state of tok. guilty until proven innocent. */ tok = yajl_tok_error; yajl_buf_clear(lexer->buf); lexer->bufInUse = 0; startOffset = *offset; break; } /* hit error or eof, bail */ goto lexed; default: lexer->error = yajl_lex_invalid_char; tok = yajl_tok_error; goto lexed; } } lexed: /* need to append to buffer if the buffer is in use or * if it's an EOF token */ if (tok == yajl_tok_eof || lexer->bufInUse) { if (!lexer->bufInUse) yajl_buf_clear(lexer->buf); lexer->bufInUse = 1; yajl_buf_append(lexer->buf, jsonText + startOffset, *offset - startOffset); lexer->bufOff = 0; if (tok != yajl_tok_eof) { *outBuf = yajl_buf_data(lexer->buf); *outLen = yajl_buf_len(lexer->buf); lexer->bufInUse = 0; } } else if (tok != yajl_tok_error) { *outBuf = jsonText + startOffset; *outLen = *offset - startOffset; } /* special case for strings. skip the quotes. */ if (tok == yajl_tok_string || tok == yajl_tok_string_with_escapes) { assert(*outLen >= 2); (*outBuf)++; *outLen -= 2; } #ifdef YAJL_LEXER_DEBUG if (tok == yajl_tok_error) { printf("lexical error: %s\n", yajl_lex_error_to_string(yajl_lex_get_error(lexer))); } else if (tok == yajl_tok_eof) { printf("EOF hit\n"); } else { printf("lexed %s: '", tokToStr(tok)); fwrite(*outBuf, 1, *outLen, stdout); printf("'\n"); } #endif return tok; } const char * yajl_lex_error_to_string(yajl_lex_error error) { switch (error) { case yajl_lex_e_ok: return "ok, no error"; case yajl_lex_string_invalid_utf8: return "invalid bytes in UTF8 string."; case yajl_lex_string_invalid_escaped_char: return "inside a string, '\\' occurs before a character " "which it may not."; case yajl_lex_string_invalid_json_char: return "invalid character inside string."; case yajl_lex_string_invalid_hex_char: return "invalid (non-hex) character occurs after '\\u' inside " "string."; case yajl_lex_invalid_char: return "invalid char in json text."; case yajl_lex_invalid_string: return "invalid string in json text."; case yajl_lex_missing_integer_after_exponent: return "malformed number, a digit is required after the exponent."; case yajl_lex_missing_integer_after_decimal: return "malformed number, a digit is required after the " "decimal point."; case yajl_lex_missing_integer_after_minus: return "malformed number, a digit is required after the " "minus sign."; case yajl_lex_unallowed_comment: return "probable comment found in input text, comments are " "not enabled."; } return "unknown error code"; } /** allows access to more specific information about the lexical * error when yajl_lex_lex returns yajl_tok_error. */ yajl_lex_error yajl_lex_get_error(yajl_lexer lexer) { if (lexer == NULL) return (yajl_lex_error) -1; return lexer->error; } size_t yajl_lex_current_line(yajl_lexer lexer) { return lexer->lineOff; } size_t yajl_lex_current_char(yajl_lexer lexer) { return lexer->charOff; } yajl_tok yajl_lex_peek(yajl_lexer lexer, const unsigned char * jsonText, size_t jsonTextLen, size_t offset) { const unsigned char * outBuf; size_t outLen; size_t bufLen = yajl_buf_len(lexer->buf); size_t bufOff = lexer->bufOff; unsigned int bufInUse = lexer->bufInUse; yajl_tok tok; tok = yajl_lex_lex(lexer, jsonText, jsonTextLen, &offset, &outBuf, &outLen); lexer->bufOff = bufOff; lexer->bufInUse = bufInUse; yajl_buf_truncate(lexer->buf, bufLen); return tok; } mongodb-1.1.5/src/libbson/src/yajl/yajl_lex.h0000664000175000017500000001017512673034026020737 0ustar jmikolajmikola/* * Copyright (c) 2007-2011, Lloyd Hilaiel * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef __YAJL_LEX_H__ #define __YAJL_LEX_H__ #include "yajl_common.h" typedef enum { yajl_tok_bool, yajl_tok_colon, yajl_tok_comma, yajl_tok_eof, yajl_tok_error, yajl_tok_left_brace, yajl_tok_left_bracket, yajl_tok_null, yajl_tok_right_brace, yajl_tok_right_bracket, /* we differentiate between integers and doubles to allow the * parser to interpret the number without re-scanning */ yajl_tok_integer, yajl_tok_double, /* we differentiate between strings which require further processing, * and strings that do not */ yajl_tok_string, yajl_tok_string_with_escapes, /* comment tokens are not currently returned to the parser, ever */ yajl_tok_comment } yajl_tok; typedef struct yajl_lexer_t * yajl_lexer; yajl_lexer yajl_lex_alloc(yajl_alloc_funcs * alloc, unsigned int allowComments, unsigned int validateUTF8); void yajl_lex_free(yajl_lexer lexer); /** * run/continue a lex. "offset" is an input/output parameter. * It should be initialized to zero for a * new chunk of target text, and upon subsetquent calls with the same * target text should passed with the value of the previous invocation. * * the client may be interested in the value of offset when an error is * returned from the lexer. This allows the client to render useful n * error messages. * * When you pass the next chunk of data, context should be reinitialized * to zero. * * Finally, the output buffer is usually just a pointer into the jsonText, * however in cases where the entity being lexed spans multiple chunks, * the lexer will buffer the entity and the data returned will be * a pointer into that buffer. * * This behavior is abstracted from client code except for the performance * implications which require that the client choose a reasonable chunk * size to get adequate performance. */ yajl_tok yajl_lex_lex(yajl_lexer lexer, const unsigned char * jsonText, size_t jsonTextLen, size_t * offset, const unsigned char ** outBuf, size_t * outLen); /** have a peek at the next token, but don't move the lexer forward */ yajl_tok yajl_lex_peek(yajl_lexer lexer, const unsigned char * jsonText, size_t jsonTextLen, size_t offset); typedef enum { yajl_lex_e_ok = 0, yajl_lex_string_invalid_utf8, yajl_lex_string_invalid_escaped_char, yajl_lex_string_invalid_json_char, yajl_lex_string_invalid_hex_char, yajl_lex_invalid_char, yajl_lex_invalid_string, yajl_lex_missing_integer_after_decimal, yajl_lex_missing_integer_after_exponent, yajl_lex_missing_integer_after_minus, yajl_lex_unallowed_comment } yajl_lex_error; const char * yajl_lex_error_to_string(yajl_lex_error error); /** allows access to more specific information about the lexical * error when yajl_lex_lex returns yajl_tok_error. */ yajl_lex_error yajl_lex_get_error(yajl_lexer lexer); /** get the current offset into the most recently lexed json string. */ size_t yajl_lex_current_offset(yajl_lexer lexer); /** get the number of lines lexed by this lexer instance */ size_t yajl_lex_current_line(yajl_lexer lexer); /** get the number of chars lexed by this lexer instance since the last * \n or \r */ size_t yajl_lex_current_char(yajl_lexer lexer); #endif mongodb-1.1.5/src/libbson/src/yajl/yajl_parse.h0000664000175000017500000002317212673034026021262 0ustar jmikolajmikola/* * Copyright (c) 2007-2011, Lloyd Hilaiel * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /** * \file yajl_parse.h * Interface to YAJL's JSON stream parsing facilities. */ #include "bson-compat.h" #include #ifndef __YAJL_PARSE_H__ #define __YAJL_PARSE_H__ #include #ifdef __cplusplus extern "C" { #endif /** error codes returned from this interface */ typedef enum { /** no error was encountered */ yajl_status_ok, /** a client callback returned zero, stopping the parse */ yajl_status_client_canceled, /** An error occured during the parse. Call yajl_get_error for * more information about the encountered error */ yajl_status_error } yajl_status; /** attain a human readable, english, string for an error */ YAJL_API const char * yajl_status_to_string(yajl_status code); /** an opaque handle to a parser */ typedef struct yajl_handle_t * yajl_handle; /** yajl is an event driven parser. this means as json elements are * parsed, you are called back to do something with the data. The * functions in this table indicate the various events for which * you will be called back. Each callback accepts a "context" * pointer, this is a void * that is passed into the yajl_parse * function which the client code may use to pass around context. * * All callbacks return an integer. If non-zero, the parse will * continue. If zero, the parse will be canceled and * yajl_status_client_canceled will be returned from the parse. * * \attention { * A note about the handling of numbers: * * yajl will only convert numbers that can be represented in a * double or a 64 bit (long long) int. All other numbers will * be passed to the client in string form using the yajl_number * callback. Furthermore, if yajl_number is not NULL, it will * always be used to return numbers, that is yajl_integer and * yajl_double will be ignored. If yajl_number is NULL but one * of yajl_integer or yajl_double are defined, parsing of a * number larger than is representable in a double or 64 bit * integer will result in a parse error. * } */ typedef struct { int (* yajl_null)(void * ctx); int (* yajl_boolean)(void * ctx, int boolVal); int (* yajl_integer)(void * ctx, int64_t integerVal); int (* yajl_double)(void * ctx, double doubleVal); /** A callback which passes the string representation of the number * back to the client. Will be used for all numbers when present */ int (* yajl_number)(void * ctx, const char * numberVal, size_t numberLen); /** strings are returned as pointers into the JSON text when, * possible, as a result, they are _not_ null padded */ int (* yajl_string)(void * ctx, const unsigned char * stringVal, size_t stringLen); int (* yajl_start_map)(void * ctx); int (* yajl_map_key)(void * ctx, const unsigned char * key, size_t stringLen); int (* yajl_end_map)(void * ctx); int (* yajl_start_array)(void * ctx); int (* yajl_end_array)(void * ctx); } yajl_callbacks; /** allocate a parser handle * \param callbacks a yajl callbacks structure specifying the * functions to call when different JSON entities * are encountered in the input text. May be NULL, * which is only useful for validation. * \param afs memory allocation functions, may be NULL for to use * C runtime library routines (malloc and friends) * \param ctx a context pointer that will be passed to callbacks. */ YAJL_API yajl_handle yajl_alloc(const yajl_callbacks * callbacks, yajl_alloc_funcs * afs, void * ctx); /** configuration parameters for the parser, these may be passed to * yajl_config() along with option specific argument(s). In general, * all configuration parameters default to *off*. */ typedef enum { /** Ignore javascript style comments present in * JSON input. Non-standard, but rather fun * arguments: toggled off with integer zero, on otherwise. * * example: * yajl_config(h, yajl_allow_comments, 1); // turn comment support on */ yajl_allow_comments = 0x01, /** * When set the parser will verify that all strings in JSON input are * valid UTF8 and will emit a parse error if this is not so. When set, * this option makes parsing slightly more expensive (~7% depending * on processor and compiler in use) * * example: * yajl_config(h, yajl_dont_validate_strings, 1); // disable utf8 checking */ yajl_dont_validate_strings = 0x02, /** * By default, upon calls to yajl_complete_parse(), yajl will * ensure the entire input text was consumed and will raise an error * otherwise. Enabling this flag will cause yajl to disable this * check. This can be useful when parsing json out of a that contains more * than a single JSON document. */ yajl_allow_trailing_garbage = 0x04, /** * Allow multiple values to be parsed by a single handle. The * entire text must be valid JSON, and values can be seperated * by any kind of whitespace. This flag will change the * behavior of the parser, and cause it continue parsing after * a value is parsed, rather than transitioning into a * complete state. This option can be useful when parsing multiple * values from an input stream. */ yajl_allow_multiple_values = 0x08, /** * When yajl_complete_parse() is called the parser will * check that the top level value was completely consumed. I.E., * if called whilst in the middle of parsing a value * yajl will enter an error state (premature EOF). Setting this * flag suppresses that check and the corresponding error. */ yajl_allow_partial_values = 0x10 } yajl_option; /** allow the modification of parser options subsequent to handle * allocation (via yajl_alloc) * \returns zero in case of errors, non-zero otherwise */ YAJL_API int yajl_config(yajl_handle h, yajl_option opt, ...); /** free a parser handle */ YAJL_API void yajl_free(yajl_handle handle); /** Parse some json! * \param hand - a handle to the json parser allocated with yajl_alloc * \param jsonText - a pointer to the UTF8 json text to be parsed * \param jsonTextLength - the length, in bytes, of input text */ YAJL_API yajl_status yajl_parse(yajl_handle hand, const unsigned char * jsonText, size_t jsonTextLength); /** Parse any remaining buffered json. * Since yajl is a stream-based parser, without an explicit end of * input, yajl sometimes can't decide if content at the end of the * stream is valid or not. For example, if "1" has been fed in, * yajl can't know whether another digit is next or some character * that would terminate the integer token. * * \param hand - a handle to the json parser allocated with yajl_alloc */ YAJL_API yajl_status yajl_complete_parse(yajl_handle hand); /** get an error string describing the state of the * parse. * * If verbose is non-zero, the message will include the JSON * text where the error occured, along with an arrow pointing to * the specific char. * * \returns A dynamically allocated string will be returned which should * be freed with yajl_free_error */ YAJL_API unsigned char * yajl_get_error(yajl_handle hand, int verbose, const unsigned char * jsonText, size_t jsonTextLength); /** * get the amount of data consumed from the last chunk passed to YAJL. * * In the case of a successful parse this can help you understand if * the entire buffer was consumed (which will allow you to handle * "junk at end of input"). * * In the event an error is encountered during parsing, this function * affords the client a way to get the offset into the most recent * chunk where the error occured. 0 will be returned if no error * was encountered. */ YAJL_API size_t yajl_get_bytes_consumed(yajl_handle hand); /** free an error returned from yajl_get_error */ YAJL_API void yajl_free_error(yajl_handle hand, unsigned char * str); #ifdef __cplusplus } #endif #endif mongodb-1.1.5/src/libbson/src/yajl/yajl_parser.c0000664000175000017500000005022412673034026021435 0ustar jmikolajmikola/* * Copyright (c) 2007-2011, Lloyd Hilaiel * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "yajl_parse.h" #include "yajl_lex.h" #include "yajl_parser.h" #include "yajl_encode.h" #include "yajl_bytestack.h" #include #include #include #include #include #include #include #include #define MAX_VALUE_TO_MULTIPLY ((INT64_MAX / 10) + (INT64_MAX % 10)) /* same semantics as strtol */ int64_t yajl_parse_integer(const unsigned char *number, unsigned int length) { int64_t ret = 0; long sign = 1; const unsigned char *pos = number; if (*pos == '-') { pos++; sign = -1; } if (*pos == '+') { pos++; } while (pos < number + length) { if ( ret > MAX_VALUE_TO_MULTIPLY ) { errno = ERANGE; return sign == 1 ? INT64_MAX : INT64_MIN; } ret *= 10; if (INT64_MAX - ret < (*pos - '0')) { errno = ERANGE; return sign == 1 ? INT64_MAX : INT64_MIN; } if (*pos < '0' || *pos > '9') { errno = ERANGE; return sign == 1 ? INT64_MAX : INT64_MIN; } ret += (*pos++ - '0'); } return sign * ret; } unsigned char * yajl_render_error_string(yajl_handle hand, const unsigned char * jsonText, size_t jsonTextLen, int verbose) { size_t offset = hand->bytesConsumed; unsigned char * str; const char * errorType = NULL; const char * errorText = NULL; char text[72]; const char * arrow = " (right here) ------^\n"; if (yajl_bs_current(hand->stateStack) == yajl_state_parse_error) { errorType = "parse"; errorText = hand->parseError; } else if (yajl_bs_current(hand->stateStack) == yajl_state_lexical_error) { errorType = "lexical"; errorText = yajl_lex_error_to_string(yajl_lex_get_error(hand->lexer)); } else { errorType = "unknown"; } { size_t memneeded = 0; memneeded += strlen(errorType); memneeded += strlen(" error"); if (errorText != NULL) { memneeded += strlen(": "); memneeded += strlen(errorText); } str = (unsigned char *) YA_MALLOC(&(hand->alloc), memneeded + 2); if (!str) return NULL; str[0] = 0; strcat((char *) str, errorType); strcat((char *) str, " error"); if (errorText != NULL) { strcat((char *) str, ": "); strcat((char *) str, errorText); } strcat((char *) str, "\n"); } /* now we append as many spaces as needed to make sure the error * falls at char 41, if verbose was specified */ if (verbose) { size_t start, end, i; size_t spacesNeeded; spacesNeeded = (offset < 30 ? 40 - offset : 10); start = (offset >= 30 ? offset - 30 : 0); end = (offset + 30 > jsonTextLen ? jsonTextLen : offset + 30); for (i=0;ialloc), (unsigned int)(strlen((char *) str) + strlen((char *) text) + strlen(arrow) + 1)); if (newStr) { newStr[0] = 0; strcat((char *) newStr, (char *) str); strcat((char *) newStr, text); strcat((char *) newStr, arrow); } YA_FREE(&(hand->alloc), str); str = (unsigned char *) newStr; } } return str; } /* check for client cancelation */ #define _CC_CHK(x) \ if (!(x)) { \ yajl_bs_set(hand->stateStack, yajl_state_parse_error); \ hand->parseError = \ "client cancelled parse via callback return value"; \ return yajl_status_client_canceled; \ } yajl_status yajl_do_finish(yajl_handle hand) { yajl_status stat; stat = yajl_do_parse(hand,(const unsigned char *) " ",1); if (stat != yajl_status_ok) return stat; switch(yajl_bs_current(hand->stateStack)) { case yajl_state_parse_error: case yajl_state_lexical_error: return yajl_status_error; case yajl_state_got_value: case yajl_state_parse_complete: return yajl_status_ok; default: if (!(hand->flags & yajl_allow_partial_values)) { yajl_bs_set(hand->stateStack, yajl_state_parse_error); hand->parseError = "premature EOF"; return yajl_status_error; } return yajl_status_ok; } } yajl_status yajl_do_parse(yajl_handle hand, const unsigned char * jsonText, size_t jsonTextLen) { yajl_tok tok; const unsigned char * buf; size_t bufLen; size_t * offset = &(hand->bytesConsumed); *offset = 0; around_again: switch (yajl_bs_current(hand->stateStack)) { case yajl_state_parse_complete: if (hand->flags & yajl_allow_multiple_values) { yajl_bs_set(hand->stateStack, yajl_state_got_value); goto around_again; } if (!(hand->flags & yajl_allow_trailing_garbage)) { if (*offset != jsonTextLen) { tok = yajl_lex_lex(hand->lexer, jsonText, jsonTextLen, offset, &buf, &bufLen); if (tok != yajl_tok_eof) { yajl_bs_set(hand->stateStack, yajl_state_parse_error); hand->parseError = "trailing garbage"; } goto around_again; } } return yajl_status_ok; case yajl_state_lexical_error: case yajl_state_parse_error: return yajl_status_error; case yajl_state_start: case yajl_state_got_value: case yajl_state_map_need_val: case yajl_state_array_need_val: case yajl_state_array_start: { /* for arrays and maps, we advance the state for this * depth, then push the state of the next depth. * If an error occurs during the parsing of the nesting * enitity, the state at this level will not matter. * a state that needs pushing will be anything other * than state_start */ yajl_state stateToPush = yajl_state_start; tok = yajl_lex_lex(hand->lexer, jsonText, jsonTextLen, offset, &buf, &bufLen); switch (tok) { case yajl_tok_eof: return yajl_status_ok; case yajl_tok_error: yajl_bs_set(hand->stateStack, yajl_state_lexical_error); goto around_again; case yajl_tok_string: if (hand->callbacks && hand->callbacks->yajl_string) { _CC_CHK(hand->callbacks->yajl_string(hand->ctx, buf, bufLen)); } break; case yajl_tok_string_with_escapes: if (hand->callbacks && hand->callbacks->yajl_string) { yajl_buf_clear(hand->decodeBuf); yajl_string_decode(hand->decodeBuf, buf, bufLen); _CC_CHK(hand->callbacks->yajl_string( hand->ctx, yajl_buf_data(hand->decodeBuf), yajl_buf_len(hand->decodeBuf))); } break; case yajl_tok_bool: if (hand->callbacks && hand->callbacks->yajl_boolean) { _CC_CHK(hand->callbacks->yajl_boolean(hand->ctx, *buf == 't')); } break; case yajl_tok_null: if (hand->callbacks && hand->callbacks->yajl_null) { _CC_CHK(hand->callbacks->yajl_null(hand->ctx)); } break; case yajl_tok_left_bracket: if (hand->callbacks && hand->callbacks->yajl_start_map) { _CC_CHK(hand->callbacks->yajl_start_map(hand->ctx)); } stateToPush = yajl_state_map_start; break; case yajl_tok_left_brace: if (hand->callbacks && hand->callbacks->yajl_start_array) { _CC_CHK(hand->callbacks->yajl_start_array(hand->ctx)); } stateToPush = yajl_state_array_start; break; case yajl_tok_integer: if (hand->callbacks) { if (hand->callbacks->yajl_number) { _CC_CHK(hand->callbacks->yajl_number( hand->ctx,(const char *) buf, bufLen)); } else if (hand->callbacks->yajl_integer) { int64_t i = 0; errno = 0; i = yajl_parse_integer(buf, (unsigned int)bufLen); if ((i == INT64_MIN || i == INT64_MAX) && errno == ERANGE) { yajl_bs_set(hand->stateStack, yajl_state_parse_error); hand->parseError = "integer overflow" ; /* try to restore error offset */ if (*offset >= bufLen) *offset -= bufLen; else *offset = 0; goto around_again; } _CC_CHK(hand->callbacks->yajl_integer(hand->ctx, i)); } } break; case yajl_tok_double: if (hand->callbacks) { if (hand->callbacks->yajl_number) { _CC_CHK(hand->callbacks->yajl_number( hand->ctx, (const char *) buf, bufLen)); } else if (hand->callbacks->yajl_double) { double d = 0.0; yajl_buf_clear(hand->decodeBuf); yajl_buf_append(hand->decodeBuf, buf, bufLen); buf = yajl_buf_data(hand->decodeBuf); errno = 0; d = strtod((char *) buf, NULL); if ((d == HUGE_VAL || d == -HUGE_VAL) && errno == ERANGE) { yajl_bs_set(hand->stateStack, yajl_state_parse_error); hand->parseError = "numeric (floating point) " "overflow"; /* try to restore error offset */ if (*offset >= bufLen) *offset -= bufLen; else *offset = 0; goto around_again; } _CC_CHK(hand->callbacks->yajl_double(hand->ctx, d)); } } break; case yajl_tok_right_brace: { if (yajl_bs_current(hand->stateStack) == yajl_state_array_start) { if (hand->callbacks && hand->callbacks->yajl_end_array) { _CC_CHK(hand->callbacks->yajl_end_array(hand->ctx)); } yajl_bs_pop(hand->stateStack); goto around_again; } /* intentional fall-through */ } case yajl_tok_colon: case yajl_tok_comma: case yajl_tok_right_bracket: yajl_bs_set(hand->stateStack, yajl_state_parse_error); hand->parseError = "unallowed token at this point in JSON text"; goto around_again; default: yajl_bs_set(hand->stateStack, yajl_state_parse_error); hand->parseError = "invalid token, internal error"; goto around_again; } /* got a value. transition depends on the state we're in. */ { yajl_state s = yajl_bs_current(hand->stateStack); if (s == yajl_state_start || s == yajl_state_got_value) { yajl_bs_set(hand->stateStack, yajl_state_parse_complete); } else if (s == yajl_state_map_need_val) { yajl_bs_set(hand->stateStack, yajl_state_map_got_val); } else { yajl_bs_set(hand->stateStack, yajl_state_array_got_val); } } if (stateToPush != yajl_state_start) { yajl_bs_push(hand->stateStack, stateToPush); } goto around_again; } case yajl_state_map_start: case yajl_state_map_need_key: { /* only difference between these two states is that in * start '}' is valid, whereas in need_key, we've parsed * a comma, and a string key _must_ follow */ tok = yajl_lex_lex(hand->lexer, jsonText, jsonTextLen, offset, &buf, &bufLen); switch (tok) { case yajl_tok_eof: return yajl_status_ok; case yajl_tok_error: yajl_bs_set(hand->stateStack, yajl_state_lexical_error); goto around_again; case yajl_tok_string_with_escapes: if (hand->callbacks && hand->callbacks->yajl_map_key) { yajl_buf_clear(hand->decodeBuf); yajl_string_decode(hand->decodeBuf, buf, bufLen); buf = yajl_buf_data(hand->decodeBuf); bufLen = yajl_buf_len(hand->decodeBuf); } /* intentional fall-through */ case yajl_tok_string: if (hand->callbacks && hand->callbacks->yajl_map_key) { _CC_CHK(hand->callbacks->yajl_map_key(hand->ctx, buf, bufLen)); } yajl_bs_set(hand->stateStack, yajl_state_map_sep); goto around_again; case yajl_tok_right_bracket: if (yajl_bs_current(hand->stateStack) == yajl_state_map_start) { if (hand->callbacks && hand->callbacks->yajl_end_map) { _CC_CHK(hand->callbacks->yajl_end_map(hand->ctx)); } yajl_bs_pop(hand->stateStack); goto around_again; } default: yajl_bs_set(hand->stateStack, yajl_state_parse_error); hand->parseError = "invalid object key (must be a string)"; goto around_again; } } case yajl_state_map_sep: { tok = yajl_lex_lex(hand->lexer, jsonText, jsonTextLen, offset, &buf, &bufLen); switch (tok) { case yajl_tok_colon: yajl_bs_set(hand->stateStack, yajl_state_map_need_val); goto around_again; case yajl_tok_eof: return yajl_status_ok; case yajl_tok_error: yajl_bs_set(hand->stateStack, yajl_state_lexical_error); goto around_again; default: yajl_bs_set(hand->stateStack, yajl_state_parse_error); hand->parseError = "object key and value must " "be separated by a colon (':')"; goto around_again; } } case yajl_state_map_got_val: { tok = yajl_lex_lex(hand->lexer, jsonText, jsonTextLen, offset, &buf, &bufLen); switch (tok) { case yajl_tok_right_bracket: if (hand->callbacks && hand->callbacks->yajl_end_map) { _CC_CHK(hand->callbacks->yajl_end_map(hand->ctx)); } yajl_bs_pop(hand->stateStack); goto around_again; case yajl_tok_comma: yajl_bs_set(hand->stateStack, yajl_state_map_need_key); goto around_again; case yajl_tok_eof: return yajl_status_ok; case yajl_tok_error: yajl_bs_set(hand->stateStack, yajl_state_lexical_error); goto around_again; default: yajl_bs_set(hand->stateStack, yajl_state_parse_error); hand->parseError = "after key and value, inside map, " "I expect ',' or '}'"; /* try to restore error offset */ if (*offset >= bufLen) *offset -= bufLen; else *offset = 0; goto around_again; } } case yajl_state_array_got_val: { tok = yajl_lex_lex(hand->lexer, jsonText, jsonTextLen, offset, &buf, &bufLen); switch (tok) { case yajl_tok_right_brace: if (hand->callbacks && hand->callbacks->yajl_end_array) { _CC_CHK(hand->callbacks->yajl_end_array(hand->ctx)); } yajl_bs_pop(hand->stateStack); goto around_again; case yajl_tok_comma: yajl_bs_set(hand->stateStack, yajl_state_array_need_val); goto around_again; case yajl_tok_eof: return yajl_status_ok; case yajl_tok_error: yajl_bs_set(hand->stateStack, yajl_state_lexical_error); goto around_again; default: yajl_bs_set(hand->stateStack, yajl_state_parse_error); hand->parseError = "after array element, I expect ',' or ']'"; goto around_again; } } } abort(); return yajl_status_error; } mongodb-1.1.5/src/libbson/src/yajl/yajl_parser.h0000664000175000017500000000473212673034026021445 0ustar jmikolajmikola/* * Copyright (c) 2007-2011, Lloyd Hilaiel * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifndef __YAJL_PARSER_H__ #define __YAJL_PARSER_H__ #include "bson-compat.h" #include "yajl_parse.h" #include "yajl_bytestack.h" #include "yajl_buf.h" #include "yajl_lex.h" typedef enum { yajl_state_start = 0, yajl_state_parse_complete, yajl_state_parse_error, yajl_state_lexical_error, yajl_state_map_start, yajl_state_map_sep, yajl_state_map_need_val, yajl_state_map_got_val, yajl_state_map_need_key, yajl_state_array_start, yajl_state_array_got_val, yajl_state_array_need_val, yajl_state_got_value, } yajl_state; struct yajl_handle_t { const yajl_callbacks * callbacks; void * ctx; yajl_lexer lexer; const char * parseError; /* the number of bytes consumed from the last client buffer, * in the case of an error this will be an error offset, in the * case of an error this can be used as the error offset */ size_t bytesConsumed; /* temporary storage for decoded strings */ yajl_buf decodeBuf; /* a stack of states. access with yajl_state_XXX routines */ yajl_bytestack stateStack; /* memory allocation routines */ yajl_alloc_funcs alloc; /* bitfield */ unsigned int flags; }; yajl_status yajl_do_parse(yajl_handle handle, const unsigned char * jsonText, size_t jsonTextLen); yajl_status yajl_do_finish(yajl_handle handle); unsigned char * yajl_render_error_string(yajl_handle hand, const unsigned char * jsonText, size_t jsonTextLen, int verbose); /* A little built in integer parsing routine with the same semantics as strtol * that's unaffected by LOCALE. */ int64_t yajl_parse_integer(const unsigned char *number, unsigned int length); #endif mongodb-1.1.5/src/libbson/src/yajl/yajl_tree.c0000664000175000017500000003262712673034026021107 0ustar jmikolajmikola/* * Copyright (c) 2010-2011 Florian Forster * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include #include #include #include #include #include "yajl_tree.h" #include "yajl_parse.h" #include "yajl_parser.h" #if defined(_WIN32) || defined(WIN32) #define snprintf sprintf_s #endif #define STATUS_CONTINUE 1 #define STATUS_ABORT 0 struct stack_elem_s; typedef struct stack_elem_s stack_elem_t; struct stack_elem_s { char * key; yajl_val value; stack_elem_t *next; }; struct context_s { stack_elem_t *stack; yajl_val root; char *errbuf; size_t errbuf_size; }; typedef struct context_s context_t; #define RETURN_ERROR(ctx,retval,...) { \ if ((ctx)->errbuf != NULL) \ snprintf ((ctx)->errbuf, (ctx)->errbuf_size, __VA_ARGS__); \ return (retval); \ } static yajl_val value_alloc (yajl_type type) { yajl_val v; v = malloc (sizeof (*v)); if (v == NULL) return (NULL); memset (v, 0, sizeof (*v)); v->type = type; return (v); } static void yajl_object_free (yajl_val v) { size_t i; if (!YAJL_IS_OBJECT(v)) return; for (i = 0; i < v->u.object.len; i++) { free((char *) v->u.object.keys[i]); v->u.object.keys[i] = NULL; yajl_tree_free (v->u.object.values[i]); v->u.object.values[i] = NULL; } free((void*) v->u.object.keys); free(v->u.object.values); free(v); } static void yajl_array_free (yajl_val v) { size_t i; if (!YAJL_IS_ARRAY(v)) return; for (i = 0; i < v->u.array.len; i++) { yajl_tree_free (v->u.array.values[i]); v->u.array.values[i] = NULL; } free(v->u.array.values); free(v); } /* * Parsing nested objects and arrays is implemented using a stack. When a new * object or array starts (a curly or a square opening bracket is read), an * appropriate value is pushed on the stack. When the end of the object is * reached (an appropriate closing bracket has been read), the value is popped * off the stack and added to the enclosing object using "context_add_value". */ static int context_push(context_t *ctx, yajl_val v) { stack_elem_t *stack; stack = malloc (sizeof (*stack)); if (stack == NULL) RETURN_ERROR (ctx, ENOMEM, "Out of memory"); memset (stack, 0, sizeof (*stack)); assert ((ctx->stack == NULL) || YAJL_IS_OBJECT (v) || YAJL_IS_ARRAY (v)); stack->value = v; stack->next = ctx->stack; ctx->stack = stack; return (0); } static yajl_val context_pop(context_t *ctx) { stack_elem_t *stack; yajl_val v; if (ctx->stack == NULL) RETURN_ERROR (ctx, NULL, "context_pop: " "Bottom of stack reached prematurely"); stack = ctx->stack; ctx->stack = stack->next; v = stack->value; free (stack); return (v); } static int object_add_keyval(context_t *ctx, yajl_val obj, char *key, yajl_val value) { const char **tmpk; yajl_val *tmpv; /* We're checking for NULL in "context_add_value" or its callers. */ assert (ctx != NULL); assert (obj != NULL); assert (key != NULL); assert (value != NULL); /* We're assuring that "obj" is an object in "context_add_value". */ assert(YAJL_IS_OBJECT(obj)); tmpk = realloc((void *) obj->u.object.keys, sizeof(*(obj->u.object.keys)) * (obj->u.object.len + 1)); if (tmpk == NULL) RETURN_ERROR(ctx, ENOMEM, "Out of memory"); obj->u.object.keys = tmpk; tmpv = realloc(obj->u.object.values, sizeof (*obj->u.object.values) * (obj->u.object.len + 1)); if (tmpv == NULL) RETURN_ERROR(ctx, ENOMEM, "Out of memory"); obj->u.object.values = tmpv; obj->u.object.keys[obj->u.object.len] = key; obj->u.object.values[obj->u.object.len] = value; obj->u.object.len++; return (0); } static int array_add_value (context_t *ctx, yajl_val array, yajl_val value) { yajl_val *tmp; /* We're checking for NULL pointers in "context_add_value" or its * callers. */ assert (ctx != NULL); assert (array != NULL); assert (value != NULL); /* "context_add_value" will only call us with array values. */ assert(YAJL_IS_ARRAY(array)); tmp = realloc(array->u.array.values, sizeof(*(array->u.array.values)) * (array->u.array.len + 1)); if (tmp == NULL) RETURN_ERROR(ctx, ENOMEM, "Out of memory"); array->u.array.values = tmp; array->u.array.values[array->u.array.len] = value; array->u.array.len++; return 0; } /* * Add a value to the value on top of the stack or the "root" member in the * context if the end of the parsing process is reached. */ static int context_add_value (context_t *ctx, yajl_val v) { /* We're checking for NULL values in all the calling functions. */ assert (ctx != NULL); assert (v != NULL); /* * There are three valid states in which this function may be called: * - There is no value on the stack => This is the only value. This is the * last step done when parsing a document. We assign the value to the * "root" member and return. * - The value on the stack is an object. In this case store the key on the * stack or, if the key has already been read, add key and value to the * object. * - The value on the stack is an array. In this case simply add the value * and return. */ if (ctx->stack == NULL) { assert (ctx->root == NULL); ctx->root = v; return (0); } else if (YAJL_IS_OBJECT (ctx->stack->value)) { if (ctx->stack->key == NULL) { if (!YAJL_IS_STRING (v)) RETURN_ERROR (ctx, EINVAL, "context_add_value: " "Object key is not a string (%#04x)", v->type); ctx->stack->key = v->u.string; v->u.string = NULL; free(v); return (0); } else /* if (ctx->key != NULL) */ { char * key; key = ctx->stack->key; ctx->stack->key = NULL; return (object_add_keyval (ctx, ctx->stack->value, key, v)); } } else if (YAJL_IS_ARRAY (ctx->stack->value)) { return (array_add_value (ctx, ctx->stack->value, v)); } else { RETURN_ERROR (ctx, EINVAL, "context_add_value: Cannot add value to " "a value of type %#04x (not a composite type)", ctx->stack->value->type); } } static int handle_string (void *ctx, const unsigned char *string, size_t string_length) { yajl_val v; v = value_alloc (yajl_t_string); if (v == NULL) RETURN_ERROR ((context_t *) ctx, STATUS_ABORT, "Out of memory"); v->u.string = malloc (string_length + 1); if (v->u.string == NULL) { free (v); RETURN_ERROR ((context_t *) ctx, STATUS_ABORT, "Out of memory"); } memcpy(v->u.string, string, string_length); v->u.string[string_length] = 0; return ((context_add_value (ctx, v) == 0) ? STATUS_CONTINUE : STATUS_ABORT); } static int handle_number (void *ctx, const char *string, size_t string_length) { yajl_val v; char *endptr; v = value_alloc(yajl_t_number); if (v == NULL) RETURN_ERROR((context_t *) ctx, STATUS_ABORT, "Out of memory"); v->u.number.r = malloc(string_length + 1); if (v->u.number.r == NULL) { free(v); RETURN_ERROR((context_t *) ctx, STATUS_ABORT, "Out of memory"); } memcpy(v->u.number.r, string, string_length); v->u.number.r[string_length] = 0; v->u.number.flags = 0; errno = 0; v->u.number.i = yajl_parse_integer((const unsigned char *) v->u.number.r, (unsigned int)strlen(v->u.number.r)); if (errno == 0) v->u.number.flags |= YAJL_NUMBER_INT_VALID; endptr = NULL; errno = 0; v->u.number.d = strtod(v->u.number.r, &endptr); if ((errno == 0) && (endptr != NULL) && (*endptr == 0)) v->u.number.flags |= YAJL_NUMBER_DOUBLE_VALID; return ((context_add_value(ctx, v) == 0) ? STATUS_CONTINUE : STATUS_ABORT); } static int handle_start_map (void *ctx) { yajl_val v; v = value_alloc(yajl_t_object); if (v == NULL) RETURN_ERROR ((context_t *) ctx, STATUS_ABORT, "Out of memory"); v->u.object.keys = NULL; v->u.object.values = NULL; v->u.object.len = 0; return ((context_push (ctx, v) == 0) ? STATUS_CONTINUE : STATUS_ABORT); } static int handle_end_map (void *ctx) { yajl_val v; v = context_pop (ctx); if (v == NULL) return (STATUS_ABORT); return ((context_add_value (ctx, v) == 0) ? STATUS_CONTINUE : STATUS_ABORT); } static int handle_start_array (void *ctx) { yajl_val v; v = value_alloc(yajl_t_array); if (v == NULL) RETURN_ERROR ((context_t *) ctx, STATUS_ABORT, "Out of memory"); v->u.array.values = NULL; v->u.array.len = 0; return ((context_push (ctx, v) == 0) ? STATUS_CONTINUE : STATUS_ABORT); } static int handle_end_array (void *ctx) { yajl_val v; v = context_pop (ctx); if (v == NULL) return (STATUS_ABORT); return ((context_add_value (ctx, v) == 0) ? STATUS_CONTINUE : STATUS_ABORT); } static int handle_boolean (void *ctx, int boolean_value) { yajl_val v; v = value_alloc (boolean_value ? yajl_t_true : yajl_t_false); if (v == NULL) RETURN_ERROR ((context_t *) ctx, STATUS_ABORT, "Out of memory"); return ((context_add_value (ctx, v) == 0) ? STATUS_CONTINUE : STATUS_ABORT); } static int handle_null (void *ctx) { yajl_val v; v = value_alloc (yajl_t_null); if (v == NULL) RETURN_ERROR ((context_t *) ctx, STATUS_ABORT, "Out of memory"); return ((context_add_value (ctx, v) == 0) ? STATUS_CONTINUE : STATUS_ABORT); } /* * Public functions */ yajl_val yajl_tree_parse (const char *input, char *error_buffer, size_t error_buffer_size) { static const yajl_callbacks callbacks = { /* null = */ handle_null, /* boolean = */ handle_boolean, /* integer = */ NULL, /* double = */ NULL, /* number = */ handle_number, /* string = */ handle_string, /* start map = */ handle_start_map, /* map key = */ handle_string, /* end map = */ handle_end_map, /* start array = */ handle_start_array, /* end array = */ handle_end_array }; yajl_handle handle; yajl_status status; char * internal_err_str; context_t ctx = { NULL, NULL, NULL, 0 }; ctx.errbuf = error_buffer; ctx.errbuf_size = error_buffer_size; if (error_buffer != NULL) memset (error_buffer, 0, error_buffer_size); handle = yajl_alloc (&callbacks, NULL, &ctx); yajl_config(handle, yajl_allow_comments, 1); status = yajl_parse(handle, (unsigned char *) input, strlen (input)); status = yajl_complete_parse (handle); if (status != yajl_status_ok) { if (error_buffer != NULL && error_buffer_size > 0) { internal_err_str = (char *) yajl_get_error(handle, 1, (const unsigned char *) input, strlen(input)); snprintf(error_buffer, error_buffer_size, "%s", internal_err_str); YA_FREE(&(handle->alloc), internal_err_str); } yajl_free (handle); return NULL; } yajl_free (handle); return (ctx.root); } yajl_val yajl_tree_get(yajl_val n, const char ** path, yajl_type type) { if (!path) return NULL; while (n && *path) { size_t i; size_t len; if (n->type != yajl_t_object) return NULL; len = n->u.object.len; for (i = 0; i < (unsigned int)len; i++) { if (!strcmp(*path, n->u.object.keys[i])) { n = n->u.object.values[i]; break; } } if (i == len) return NULL; path++; } if (n && type != yajl_t_any && type != n->type) n = NULL; return n; } void yajl_tree_free (yajl_val v) { if (v == NULL) return; if (YAJL_IS_STRING(v)) { free(v->u.string); free(v); } else if (YAJL_IS_NUMBER(v)) { free(v->u.number.r); free(v); } else if (YAJL_GET_OBJECT(v)) { yajl_object_free(v); } else if (YAJL_GET_ARRAY(v)) { yajl_array_free(v); } else /* if (yajl_t_true or yajl_t_false or yajl_t_null) */ { free(v); } } mongodb-1.1.5/src/libbson/src/yajl/yajl_tree.h0000664000175000017500000001600312673034026021102 0ustar jmikolajmikola/* * Copyright (c) 2010-2011 Florian Forster * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /** * \file yajl_tree.h * * Parses JSON data and returns the data in tree form. * * \author Florian Forster * \date August 2010 * * This interface makes quick parsing and extraction of * smallish JSON docs trivial: * * \include example/parse_config.c */ #ifndef YAJL_TREE_H #define YAJL_TREE_H 1 #include #ifdef __cplusplus extern "C" { #endif /** possible data types that a yajl_val_s can hold */ typedef enum { yajl_t_string = 1, yajl_t_number = 2, yajl_t_object = 3, yajl_t_array = 4, yajl_t_true = 5, yajl_t_false = 6, yajl_t_null = 7, /** The any type isn't valid for yajl_val_s.type, but can be * used as an argument to routines like yajl_tree_get(). */ yajl_t_any = 8 } yajl_type; #define YAJL_NUMBER_INT_VALID 0x01 #define YAJL_NUMBER_DOUBLE_VALID 0x02 /** A pointer to a node in the parse tree */ typedef struct yajl_val_s * yajl_val; /** * A JSON value representation capable of holding one of the seven * types above. For "string", "number", "object", and "array" * additional data is available in the union. The "YAJL_IS_*" * and "YAJL_GET_*" macros below allow type checking and convenient * value extraction. */ struct yajl_val_s { /** Type of the value contained. Use the "YAJL_IS_*" macors to check for a * specific type. */ yajl_type type; /** Type-specific data. You may use the "YAJL_GET_*" macros to access these * members. */ union { char * string; struct { long long i; /*< integer value, if representable. */ double d; /*< double value, if representable. */ /** Signals whether the \em i and \em d members are * valid. See \c YAJL_NUMBER_INT_VALID and * \c YAJL_NUMBER_DOUBLE_VALID. */ char *r; /*< unparsed number in string form. */ unsigned int flags; } number; struct { const char **keys; /*< Array of keys */ yajl_val *values; /*< Array of values. */ size_t len; /*< Number of key-value-pairs. */ } object; struct { yajl_val *values; /*< Array of elements. */ size_t len; /*< Number of elements. */ } array; } u; }; /** * Parse a string. * * Parses an null-terminated string containing JSON data and returns a pointer * to the top-level value (root of the parse tree). * * \param input Pointer to a null-terminated utf8 string containing * JSON data. * \param error_buffer Pointer to a buffer in which an error message will * be stored if \em yajl_tree_parse fails, or * \c NULL. The buffer will be initialized before * parsing, so its content will be destroyed even if * \em yajl_tree_parse succeeds. * \param error_buffer_size Size of the memory area pointed to by * \em error_buffer_size. If \em error_buffer_size is * \c NULL, this argument is ignored. * * \returns Pointer to the top-level value or \c NULL on error. The memory * pointed to must be freed using \em yajl_tree_free. In case of an error, a * null terminated message describing the error in more detail is stored in * \em error_buffer if it is not \c NULL. */ YAJL_API yajl_val yajl_tree_parse (const char *input, char *error_buffer, size_t error_buffer_size); /** * Free a parse tree returned by "yajl_tree_parse". * * \param v Pointer to a JSON value returned by "yajl_tree_parse". Passing NULL * is valid and results in a no-op. */ YAJL_API void yajl_tree_free (yajl_val v); /** * Access a nested value inside a tree. * * \param parent the node under which you'd like to extract values. * \param path A null terminated array of strings, each the name of an object key * \param type the yajl_type of the object you seek, or yajl_t_any if any will do. * * \returns a pointer to the found value, or NULL if we came up empty. * * Future Ideas: it'd be nice to move path to a string and implement support for * a teeny tiny micro language here, so you can extract array elements, do things * like .first and .last, even .length. Inspiration from JSONPath and css selectors? * No it wouldn't be fast, but that's not what this API is about. */ YAJL_API yajl_val yajl_tree_get(yajl_val parent, const char ** path, yajl_type type); /* Various convenience macros to check the type of a `yajl_val` */ #define YAJL_IS_STRING(v) (((v) != NULL) && ((v)->type == yajl_t_string)) #define YAJL_IS_NUMBER(v) (((v) != NULL) && ((v)->type == yajl_t_number)) #define YAJL_IS_INTEGER(v) (YAJL_IS_NUMBER(v) && ((v)->u.number.flags & YAJL_NUMBER_INT_VALID)) #define YAJL_IS_DOUBLE(v) (YAJL_IS_NUMBER(v) && ((v)->u.number.flags & YAJL_NUMBER_DOUBLE_VALID)) #define YAJL_IS_OBJECT(v) (((v) != NULL) && ((v)->type == yajl_t_object)) #define YAJL_IS_ARRAY(v) (((v) != NULL) && ((v)->type == yajl_t_array )) #define YAJL_IS_TRUE(v) (((v) != NULL) && ((v)->type == yajl_t_true )) #define YAJL_IS_FALSE(v) (((v) != NULL) && ((v)->type == yajl_t_false )) #define YAJL_IS_NULL(v) (((v) != NULL) && ((v)->type == yajl_t_null )) /** Given a yajl_val_string return a ptr to the bare string it contains, * or NULL if the value is not a string. */ #define YAJL_GET_STRING(v) (YAJL_IS_STRING(v) ? (v)->u.string : NULL) /** Get the string representation of a number. You should check type first, * perhaps using YAJL_IS_NUMBER */ #define YAJL_GET_NUMBER(v) ((v)->u.number.r) /** Get the double representation of a number. You should check type first, * perhaps using YAJL_IS_DOUBLE */ #define YAJL_GET_DOUBLE(v) ((v)->u.number.d) /** Get the 64bit (long long) integer representation of a number. You should * check type first, perhaps using YAJL_IS_INTEGER */ #define YAJL_GET_INTEGER(v) ((v)->u.number.i) /** Get a pointer to a yajl_val_object or NULL if the value is not an object. */ #define YAJL_GET_OBJECT(v) (YAJL_IS_OBJECT(v) ? &(v)->u.object : NULL) /** Get a pointer to a yajl_val_array or NULL if the value is not an object. */ #define YAJL_GET_ARRAY(v) (YAJL_IS_ARRAY(v) ? &(v)->u.array : NULL) #ifdef __cplusplus } #endif #endif /* YAJL_TREE_H */ mongodb-1.1.5/src/libbson/src/yajl/yajl_version.c0000664000175000017500000000012212673034026021616 0ustar jmikolajmikola#include int yajl_version(void) { return YAJL_VERSION; } mongodb-1.1.5/src/libbson/src/yajl/yajl_version.h0000664000175000017500000000055312673034026021633 0ustar jmikolajmikola#ifndef YAJL_VERSION_H_ #define YAJL_VERSION_H_ #include #define YAJL_MAJOR 2 #define YAJL_MINOR 0 #define YAJL_MICRO 4 #define YAJL_VERSION ((YAJL_MAJOR * 10000) + (YAJL_MINOR * 100) + YAJL_MICRO) #ifdef __cplusplus extern "C" { #endif extern int YAJL_API yajl_version(void); #ifdef __cplusplus } #endif #endif /* YAJL_VERSION_H_ */ mongodb-1.1.5/src/libbson/VERSION_CURRENT0000664000175000017500000000000512673034026017472 0ustar jmikolajmikola1.3.3mongodb-1.1.5/src/libbson/VERSION_RELEASED0000664000175000017500000000000512673034026017534 0ustar jmikolajmikola1.3.3mongodb-1.1.5/src/libmongoc/build/autotools/m4/ac_check_typedef.m40000664000175000017500000000264012673034026024722 0ustar jmikolajmikoladnl @synopsis AC_CHECK_TYPEDEF_(TYPEDEF, HEADER [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]) dnl dnl check if the given typedef-name is recognized as a type. The trick dnl is to use a sizeof(TYPEDEF) and see if the compiler is happy with dnl that. dnl dnl this can be thought of as a mixture of dnl AC_CHECK_TYPE(TYPEDEF,DEFAULT) and dnl AC_CHECK_LIB(LIBRARY,FUNCTION,ACTION-IF-FOUND,ACTION-IF-NOT-FOUND) dnl dnl a convenience macro AC_CHECK_TYPEDEF_ is provided that will not dnl emit any message to the user - it just executes one of the actions. dnl dnl @category C dnl @author Guido U. Draheim dnl @version 2006-10-13 dnl @license GPLWithACException AC_DEFUN([AC_CHECK_TYPEDEF_], [dnl ac_lib_var=`echo $1['_']$2 | sed 'y%./+-%__p_%'` AC_CACHE_VAL(ac_cv_lib_$ac_lib_var, [ eval "ac_cv_type_$ac_lib_var='not-found'" ac_cv_check_typedef_header=`echo ifelse([$2], , stddef.h, $2)` AC_TRY_COMPILE( [#include <$ac_cv_check_typedef_header>], [int x = sizeof($1); x = x;], eval "ac_cv_type_$ac_lib_var=yes" , eval "ac_cv_type_$ac_lib_var=no" ) if test `eval echo '$ac_cv_type_'$ac_lib_var` = "no" ; then ifelse([$4], , :, $4) else ifelse([$3], , :, $3) fi ])]) dnl AC_CHECK_TYPEDEF(TYPEDEF, HEADER [, ACTION-IF-FOUND, dnl [, ACTION-IF-NOT-FOUND ]]) AC_DEFUN([AC_CHECK_TYPEDEF], [dnl AC_MSG_CHECKING([for $1 in $2]) AC_CHECK_TYPEDEF_($1,$2,AC_MSG_RESULT(yes),AC_MSG_RESULT(no))dnl ]) mongodb-1.1.5/src/libmongoc/build/autotools/m4/ac_compile_check_sizeof.m40000664000175000017500000000156612673034026026277 0ustar jmikolajmikolaAC_DEFUN([AC_COMPILE_CHECK_SIZEOF], [changequote(<<, >>)dnl dnl The name to #define. define(<<AC_TYPE_NAME>>, translit(sizeof_$1, [a-z *], [A-Z_P]))dnl dnl The cache variable name. define(<<AC_CV_NAME>>, translit(ac_cv_sizeof_$1, [ *], [_p]))dnl changequote([, ])dnl AC_MSG_CHECKING(size of $1) AC_CACHE_VAL(AC_CV_NAME, [for ac_size in 4 8 1 2 16 $2 ; do # List sizes in rough order of prevalence. AC_TRY_COMPILE([#include "confdefs.h" #include <sys/types.h> $2 ], [switch (0) case 0: case (sizeof ($1) == $ac_size):;], AC_CV_NAME=$ac_size) if test x$AC_CV_NAME != x ; then break; fi done ]) if test x$AC_CV_NAME = x ; then AC_MSG_ERROR([cannot determine a size for $1]) fi AC_MSG_RESULT($AC_CV_NAME) AC_DEFINE_UNQUOTED(AC_TYPE_NAME, $AC_CV_NAME, [The number of bytes in type $1]) undefine([AC_TYPE_NAME])dnl undefine([AC_CV_NAME])dnl ]) mongodb-1.1.5/src/libmongoc/build/autotools/m4/ac_create_stdint_h.m40000664000175000017500000003662212673034026025273 0ustar jmikolajmikoladnl @synopsis AC_CREATE_STDINT_H [( HEADER-TO-GENERATE [, HEDERS-TO-CHECK])] dnl dnl the "ISO C9X: 7.18 Integer types " section requires the dnl existence of an include file that defines a set of dnl typedefs, especially uint8_t,int32_t,uintptr_t. Many older dnl installations will not provide this file, but some will have the dnl very same definitions in . In other enviroments we can dnl use the inet-types in which would define the typedefs dnl int8_t and u_int8_t respectivly. dnl dnl This macros will create a local "_stdint.h" or the headerfile given dnl as an argument. In many cases that file will just have a singular dnl "#include " or "#include " statement, while dnl in other environments it will provide the set of basic 'stdint's dnl defined: dnl int8_t,uint8_t,int16_t,uint16_t,int32_t,uint32_t,intptr_t,uintptr_t dnl int_least32_t.. int_fast32_t.. intmax_t which may or may not rely dnl on the definitions of other files, or using the dnl AC_COMPILE_CHECK_SIZEOF macro to determine the actual sizeof each dnl type. dnl dnl if your header files require the stdint-types you will want to dnl create an installable file mylib-int.h that all your other dnl installable header may include. So if you have a library package dnl named "mylib", just use dnl dnl AC_CREATE_STDINT_H(mylib-int.h) dnl dnl in configure.in and go to install that very header file in dnl Makefile.am along with the other headers (mylib.h) - and the dnl mylib-specific headers can simply use "#include " to dnl obtain the stdint-types. dnl dnl Remember, if the system already had a valid , the dnl generated file will include it directly. No need for fuzzy dnl HAVE_STDINT_H things... dnl dnl (note also the newer variant AX_CREATE_STDINT_H of this macro) dnl dnl @category C dnl @author Guido U. Draheim dnl @version 2003-05-21 dnl @license GPLWithACException AC_DEFUN([AC_CREATE_STDINT_H], [# ------ AC CREATE STDINT H ------------------------------------- AC_MSG_CHECKING([for stdint-types....]) ac_stdint_h=`echo ifelse($1, , _stdint.h, $1)` if test "$ac_stdint_h" = "stdint.h" ; then AC_MSG_RESULT("(are you sure you want them in ./stdint.h?)") elif test "$ac_stdint_h" = "inttypes.h" ; then AC_MSG_RESULT("(are you sure you want them in ./inttypes.h?)") else AC_MSG_RESULT("(putting them into $ac_stdint_h)") mkdir -p $(dirname "$ac_stdint_h") fi inttype_headers=`echo inttypes.h sys/inttypes.h sys/inttypes.h $2 \ | sed -e 's/,/ /g'` ac_cv_header_stdint_x="no-file" ac_cv_header_stdint_o="no-file" ac_cv_header_stdint_u="no-file" for i in stdint.h $inttype_headers ; do unset ac_cv_type_uintptr_t unset ac_cv_type_uint64_t _AC_CHECK_TYPE_NEW(uintptr_t,[ac_cv_header_stdint_x=$i],dnl continue,[#include <$i>]) AC_CHECK_TYPE(uint64_t,[and64="(uint64_t too)"],[and64=""],[#include<$i>]) AC_MSG_RESULT(... seen our uintptr_t in $i $and64) break; done if test "$ac_cv_header_stdint_x" = "no-file" ; then for i in stdint.h $inttype_headers ; do unset ac_cv_type_uint32_t unset ac_cv_type_uint64_t AC_CHECK_TYPE(uint32_t,[ac_cv_header_stdint_o=$i],dnl continue,[#include <$i>]) AC_CHECK_TYPE(uint64_t,[and64="(uint64_t too)"],[and64=""],[#include<$i>]) AC_MSG_RESULT(... seen our uint32_t in $i $and64) break; done if test "$ac_cv_header_stdint_o" = "no-file" ; then for i in sys/types.h $inttype_headers ; do unset ac_cv_type_u_int32_t unset ac_cv_type_u_int64_t AC_CHECK_TYPE(u_int32_t,[ac_cv_header_stdint_u=$i],dnl continue,[#include <$i>]) AC_CHECK_TYPE(uint64_t,[and64="(u_int64_t too)"],[and64=""],[#include<$i>]) AC_MSG_RESULT(... seen our u_int32_t in $i $and64) break; done fi fi # ----------------- DONE inttypes.h checks MAYBE C basic types -------- if test "$ac_cv_header_stdint_x" = "no-file" ; then AC_COMPILE_CHECK_SIZEOF(char) AC_COMPILE_CHECK_SIZEOF(short) AC_COMPILE_CHECK_SIZEOF(int) AC_COMPILE_CHECK_SIZEOF(long) AC_COMPILE_CHECK_SIZEOF(void*) ac_cv_header_stdint_test="yes" else ac_cv_header_stdint_test="no" fi # ----------------- DONE inttypes.h checks START header ------------- _ac_stdint_h=AS_TR_CPP(_$ac_stdint_h) AC_MSG_RESULT(creating $ac_stdint_h : $_ac_stdint_h) echo "#ifndef" $_ac_stdint_h >$ac_stdint_h echo "#define" $_ac_stdint_h "1" >>$ac_stdint_h echo "#ifndef" _GENERATED_STDINT_H >>$ac_stdint_h echo "#define" _GENERATED_STDINT_H '"'$PACKAGE $VERSION'"' >>$ac_stdint_h if test "$GCC" = "yes" ; then echo "/* generated using a gnu compiler version" `$CC --version` "*/" \ >>$ac_stdint_h else echo "/* generated using $CC */" >>$ac_stdint_h fi echo "" >>$ac_stdint_h if test "$ac_cv_header_stdint_x" != "no-file" ; then ac_cv_header_stdint="$ac_cv_header_stdint_x" elif test "$ac_cv_header_stdint_o" != "no-file" ; then ac_cv_header_stdint="$ac_cv_header_stdint_o" elif test "$ac_cv_header_stdint_u" != "no-file" ; then ac_cv_header_stdint="$ac_cv_header_stdint_u" else ac_cv_header_stdint="stddef.h" fi # ----------------- See if int_least and int_fast types are present unset ac_cv_type_int_least32_t unset ac_cv_type_int_fast32_t AC_CHECK_TYPE(int_least32_t,,,[#include <$ac_cv_header_stdint>]) AC_CHECK_TYPE(int_fast32_t,,,[#include<$ac_cv_header_stdint>]) if test "$ac_cv_header_stdint" != "stddef.h" ; then if test "$ac_cv_header_stdint" != "stdint.h" ; then AC_MSG_RESULT(..adding include stddef.h) echo "#include " >>$ac_stdint_h fi ; fi AC_MSG_RESULT(..adding include $ac_cv_header_stdint) echo "#include <$ac_cv_header_stdint>" >>$ac_stdint_h echo "" >>$ac_stdint_h # ----------------- DONE header START basic int types ------------- if test "$ac_cv_header_stdint_x" = "no-file" ; then AC_MSG_RESULT(... need to look at C basic types) dnl ac_cv_header_stdint_test="yes" # moved up before creating the file else AC_MSG_RESULT(... seen good stdint.h inttypes) dnl ac_cv_header_stdint_test="no" # moved up before creating the file fi if test "$ac_cv_header_stdint_u" != "no-file" ; then AC_MSG_RESULT(... seen bsd/sysv typedefs) cat >>$ac_stdint_h <>$ac_stdint_h <>$ac_stdint_h <>$ac_stdint_h <>$ac_stdint_h <>$ac_stdint_h <>$ac_stdint_h <>$ac_stdint_h <>$ac_stdint_h <>$ac_stdint_h <>$ac_stdint_h <>$ac_stdint_h < 199901L #ifndef _HAVE_UINT64_T #define _HAVE_UINT64_T typedef long long int64_t; typedef unsigned long long uint64_t; #endif #elif !defined __STRICT_ANSI__ #if defined _MSC_VER || defined __WATCOMC__ || defined __BORLANDC__ #ifndef _HAVE_UINT64_T #define _HAVE_UINT64_T typedef __int64 int64_t; typedef unsigned __int64 uint64_t; #endif #elif defined __GNUC__ || defined __MWERKS__ || defined __ELF__ dnl /* note: all ELF-systems seem to have loff-support which needs 64-bit */ #if !defined _NO_LONGLONG #ifndef _HAVE_UINT64_T #define _HAVE_UINT64_T typedef long long int64_t; typedef unsigned long long uint64_t; #endif #endif #elif defined __alpha || (defined __mips && defined _ABIN32) #if !defined _NO_LONGLONG #ifndef _HAVE_UINT64_T #define _HAVE_UINT64_T typedef long int64_t; typedef unsigned long uint64_t; #endif #endif /* compiler/cpu type ... or just ISO C99 */ #endif #endif EOF # plus a default 64-bit for systems that are likely to be 64-bit ready case "$ac_cv_sizeof_x:$ac_cv_sizeof_voidp:$ac_cv_sizeof_long" in 1:2:8:8) AC_MSG_RESULT(..adding uint64_t default, normal 64-bit system) cat >>$ac_stdint_h <>$ac_stdint_h <>$ac_stdint_h <>$ac_stdint_h <>$ac_stdint_h <>$ac_stdint_h <>$ac_stdint_h <>$ac_stdint_h <>$ac_stdint_h <>$ac_stdint_h <>$ac_stdint_h <>$ac_stdint_h <>$ac_stdint_h < dnl $Id: as-compiler-flag.m4,v 1.1 2005/12/15 23:35:19 ds Exp $ dnl AS_COMPILER_FLAG(CFLAGS, ACTION-IF-ACCEPTED, [ACTION-IF-NOT-ACCEPTED]) dnl Tries to compile with the given CFLAGS. dnl Runs ACTION-IF-ACCEPTED if the compiler can compile with the flags, dnl and ACTION-IF-NOT-ACCEPTED otherwise. AC_DEFUN([AS_COMPILER_FLAG], [ AC_MSG_CHECKING([to see if compiler understands $1]) save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $1" AC_TRY_COMPILE([ ], [], [flag_ok=yes], [flag_ok=no]) CFLAGS="$save_CFLAGS" if test "X$flag_ok" = Xyes ; then m4_ifvaln([$2],[$2]) true else m4_ifvaln([$3],[$3]) true fi AC_MSG_RESULT([$flag_ok]) ]) dnl AS_COMPILER_FLAGS(VAR, FLAGS) dnl Tries to compile with the given CFLAGS. AC_DEFUN([AS_COMPILER_FLAGS], [ list=$2 flags_supported="" flags_unsupported="" AC_MSG_CHECKING([for supported compiler flags]) for each in $list do save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $each" AC_TRY_COMPILE([ ], [], [flag_ok=yes], [flag_ok=no]) CFLAGS="$save_CFLAGS" if test "X$flag_ok" = Xyes ; then flags_supported="$flags_supported $each" else flags_unsupported="$flags_unsupported $each" fi done AC_MSG_RESULT([$flags_supported]) if test "X$flags_unsupported" != X ; then AC_MSG_WARN([unsupported compiler flags: $flags_unsupported]) fi $1="$$1 $flags_supported" ]) mongodb-1.1.5/src/libmongoc/build/autotools/m4/ax_check_compile_flag.m40000664000175000017500000000625112673034026025732 0ustar jmikolajmikola# =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html # =========================================================================== # # SYNOPSIS # # AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS]) # # DESCRIPTION # # Check whether the given FLAG works with the current language's compiler # or gives an error. (Warnings, however, are ignored) # # ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on # success/failure. # # If EXTRA-FLAGS is defined, it is added to the current language's default # flags (e.g. CFLAGS) when the check is done. The check is thus made with # the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to # force the compiler to issue an error when a bad flag is given. # # NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this # macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG. # # LICENSE # # Copyright (c) 2008 Guido U. Draheim # Copyright (c) 2011 Maarten Bosmans # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation, either version 3 of the License, or (at your # option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 2 AC_DEFUN([AX_CHECK_COMPILE_FLAG], [AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [ ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1" AC_COMPILE_IFELSE([AC_LANG_PROGRAM()], [AS_VAR_SET(CACHEVAR,[yes])], [AS_VAR_SET(CACHEVAR,[no])]) _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags]) AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes], [m4_default([$2], :)], [m4_default([$3], :)]) AS_VAR_POPDEF([CACHEVAR])dnl ])dnl AX_CHECK_COMPILE_FLAGS mongodb-1.1.5/src/libmongoc/build/autotools/m4/ax_check_link_flag.m40000664000175000017500000000576012673034026025243 0ustar jmikolajmikola# =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_check_link_flag.html # =========================================================================== # # SYNOPSIS # # AX_CHECK_LINK_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS]) # # DESCRIPTION # # Check whether the given FLAG works with the linker or gives an error. # (Warnings, however, are ignored) # # ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on # success/failure. # # If EXTRA-FLAGS is defined, it is added to the linker's default flags # when the check is done. The check is thus made with the flags: "LDFLAGS # EXTRA-FLAGS FLAG". This can for example be used to force the linker to # issue an error when a bad flag is given. # # NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this # macro in sync with AX_CHECK_{PREPROC,COMPILE}_FLAG. # # LICENSE # # Copyright (c) 2008 Guido U. Draheim # Copyright (c) 2011 Maarten Bosmans # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation, either version 3 of the License, or (at your # option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 2 AC_DEFUN([AX_CHECK_LINK_FLAG], [AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_ldflags_$4_$1])dnl AC_CACHE_CHECK([whether the linker accepts $1], CACHEVAR, [ ax_check_save_flags=$LDFLAGS LDFLAGS="$LDFLAGS $4 $1" AC_LINK_IFELSE([AC_LANG_PROGRAM()], [AS_VAR_SET(CACHEVAR,[yes])], [AS_VAR_SET(CACHEVAR,[no])]) LDFLAGS=$ax_check_save_flags]) AS_IF([test x"AS_VAR_GET(CACHEVAR)" = xyes], [m4_default([$2], :)], [m4_default([$3], :)]) AS_VAR_POPDEF([CACHEVAR])dnl ])dnl AX_CHECK_LINK_FLAGS mongodb-1.1.5/src/libmongoc/build/autotools/m4/ax_pthread.m40000664000175000017500000003267612673034026023615 0ustar jmikolajmikola# =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_pthread.html # =========================================================================== # # SYNOPSIS # # AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) # # DESCRIPTION # # This macro figures out how to build C programs using POSIX threads. It # sets the PTHREAD_LIBS output variable to the threads library and linker # flags, and the PTHREAD_CFLAGS output variable to any special C compiler # flags that are needed. (The user can also force certain compiler # flags/libs to be tested by setting these environment variables.) # # Also sets PTHREAD_CC to any special C compiler that is needed for # multi-threaded programs (defaults to the value of CC otherwise). (This # is necessary on AIX to use the special cc_r compiler alias.) # # NOTE: You are assumed to not only compile your program with these flags, # but also link it with them as well. e.g. you should link with # $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS # # If you are only building threads programs, you may wish to use these # variables in your default LIBS, CFLAGS, and CC: # # LIBS="$PTHREAD_LIBS $LIBS" # CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # CC="$PTHREAD_CC" # # In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant # has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name # (e.g. PTHREAD_CREATE_UNDETACHED on AIX). # # Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the # PTHREAD_PRIO_INHERIT symbol is defined when compiling with # PTHREAD_CFLAGS. # # ACTION-IF-FOUND is a list of shell commands to run if a threads library # is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it # is not found. If ACTION-IF-FOUND is not specified, the default action # will define HAVE_PTHREAD. # # Please let the authors know if this macro fails on any platform, or if # you have any other suggestions or comments. This macro was based on work # by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help # from M. Frigo), as well as ac_pthread and hb_pthread macros posted by # Alejandro Forero Cuervo to the autoconf macro repository. We are also # grateful for the helpful feedback of numerous users. # # Updated for Autoconf 2.68 by Daniel Richard G. # # LICENSE # # Copyright (c) 2008 Steven G. Johnson # Copyright (c) 2011 Daniel Richard G. # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation, either version 3 of the License, or (at your # option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 21 AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) AC_DEFUN([AX_PTHREAD], [ AC_REQUIRE([AC_CANONICAL_HOST]) AC_LANG_PUSH([C]) ax_pthread_ok=no # We used to check for pthread.h first, but this fails if pthread.h # requires special compiler flags (e.g. on True64 or Sequent). # It gets checked for in the link test anyway. # First of all, check if the user has set any of the PTHREAD_LIBS, # etcetera environment variables, and if threads linking works using # them: if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" save_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) AC_TRY_LINK_FUNC([pthread_join], [ax_pthread_ok=yes]) AC_MSG_RESULT([$ax_pthread_ok]) if test x"$ax_pthread_ok" = xno; then PTHREAD_LIBS="" PTHREAD_CFLAGS="" fi LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" fi # We must check for the threads library under a number of different # names; the ordering is very important because some systems # (e.g. DEC) have both -lpthread and -lpthreads, where one of the # libraries is broken (non-POSIX). # Create a list of thread flags to try. Items starting with a "-" are # C compiler flags, and other items are library names, except for "none" # which indicates that we try without any flags at all, and "pthread-config" # which is a program returning the flags for the Pth emulation library. ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" # The ordering *is* (sometimes) important. Some notes on the # individual items follow: # pthreads: AIX (must check this before -lpthread) # none: in case threads are in libc; should be tried before -Kthread and # other compiler flags to prevent continual compiler warnings # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) # -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) # -pthreads: Solaris/gcc # -mthreads: Mingw32/gcc, Lynx/gcc # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it # doesn't hurt to check since this sometimes defines pthreads too; # also defines -D_REENTRANT) # ... -mt is also the pthreads flag for HP/aCC # pthread: Linux, etcetera # --thread-safe: KAI C++ # pthread-config: use pthread-config program (for GNU Pth library) case ${host_os} in solaris*) # On Solaris (at least, for some versions), libc contains stubbed # (non-functional) versions of the pthreads routines, so link-based # tests will erroneously succeed. (We need to link with -pthreads/-mt/ # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather # a function called by this macro, so we could check for that, but # who knows whether they'll stub that too in a future libc.) So, # we'll just look for -pthreads and -lpthread first: ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags" ;; darwin*) ax_pthread_flags="-pthread $ax_pthread_flags" ;; esac # Clang doesn't consider unrecognized options an error unless we specify # -Werror. We throw in some extra Clang-specific options to ensure that # this doesn't happen for GCC, which also accepts -Werror. AC_MSG_CHECKING([if compiler needs -Werror to reject unknown flags]) save_CFLAGS="$CFLAGS" ax_pthread_extra_flags="-Werror" CFLAGS="$CFLAGS $ax_pthread_extra_flags -Wunknown-warning-option -Wsizeof-array-argument" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([int foo(void);],[foo()])], [AC_MSG_RESULT([yes])], [ax_pthread_extra_flags= AC_MSG_RESULT([no])]) CFLAGS="$save_CFLAGS" if test x"$ax_pthread_ok" = xno; then for flag in $ax_pthread_flags; do case $flag in none) AC_MSG_CHECKING([whether pthreads work without any flags]) ;; -*) AC_MSG_CHECKING([whether pthreads work with $flag]) PTHREAD_CFLAGS="$flag" ;; pthread-config) AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no]) if test x"$ax_pthread_config" = xno; then continue; fi PTHREAD_CFLAGS="`pthread-config --cflags`" PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" ;; *) AC_MSG_CHECKING([for the pthreads library -l$flag]) PTHREAD_LIBS="-l$flag" ;; esac save_LIBS="$LIBS" save_CFLAGS="$CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS $ax_pthread_extra_flags" # Check for various functions. We must include pthread.h, # since some functions may be macros. (On the Sequent, we # need a special flag -Kthread to make this header compile.) # We check for pthread_join because it is in -lpthread on IRIX # while pthread_create is in libc. We check for pthread_attr_init # due to DEC craziness with -lpthreads. We check for # pthread_cleanup_push because it is one of the few pthread # functions on Solaris that doesn't have a non-functional libc stub. # We try pthread_create on general principles. AC_LINK_IFELSE([AC_LANG_PROGRAM([#include static void routine(void *a) { a = 0; } static void *start_routine(void *a) { return a; }], [pthread_t th; pthread_attr_t attr; pthread_create(&th, 0, start_routine, 0); pthread_join(th, 0); pthread_attr_init(&attr); pthread_cleanup_push(routine, 0); pthread_cleanup_pop(0) /* ; */])], [ax_pthread_ok=yes], []) LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" AC_MSG_RESULT([$ax_pthread_ok]) if test "x$ax_pthread_ok" = xyes; then break; fi PTHREAD_LIBS="" PTHREAD_CFLAGS="" done fi # Various other checks: if test "x$ax_pthread_ok" = xyes; then save_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. AC_MSG_CHECKING([for joinable pthread attribute]) attr_name=unknown for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], [int attr = $attr; return attr /* ; */])], [attr_name=$attr; break], []) done AC_MSG_RESULT([$attr_name]) if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], [$attr_name], [Define to necessary symbol if this constant uses a non-standard name on your system.]) fi AC_MSG_CHECKING([if more special flags are required for pthreads]) flag=no case ${host_os} in aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";; osf* | hpux*) flag="-D_REENTRANT";; solaris*) if test "$GCC" = "yes"; then flag="-D_REENTRANT" else # TODO: What about Clang on Solaris? flag="-mt -D_REENTRANT" fi ;; esac AC_MSG_RESULT([$flag]) if test "x$flag" != xno; then PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" fi AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], [ax_cv_PTHREAD_PRIO_INHERIT], [ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[int i = PTHREAD_PRIO_INHERIT;]])], [ax_cv_PTHREAD_PRIO_INHERIT=yes], [ax_cv_PTHREAD_PRIO_INHERIT=no]) ]) AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"], [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.])]) LIBS="$save_LIBS" CFLAGS="$save_CFLAGS" # More AIX lossage: compile with *_r variant if test "x$GCC" != xyes; then case $host_os in aix*) AS_CASE(["x/$CC"], [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], [#handle absolute path differently from PATH based program lookup AS_CASE(["x$CC"], [x/*], [AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])], [AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])]) ;; esac fi fi test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" AC_SUBST([PTHREAD_LIBS]) AC_SUBST([PTHREAD_CFLAGS]) AC_SUBST([PTHREAD_CC]) # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: if test x"$ax_pthread_ok" = xyes; then ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1]) : else ax_pthread_ok=no $2 fi AC_LANG_POP ])dnl AX_PTHREAD mongodb-1.1.5/src/libmongoc/build/autotools/m4/libtool.m40000644000175000017500000106011112673034026023122 0ustar jmikolajmikola# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. m4_define([_LT_COPYING], [dnl # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. # # GNU Libtool is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, or # obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ]) # serial 57 LT_INIT # LT_PREREQ(VERSION) # ------------------ # Complain and exit if this libtool version is less that VERSION. m4_defun([LT_PREREQ], [m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, [m4_default([$3], [m4_fatal([Libtool version $1 or higher is required], 63)])], [$2])]) # _LT_CHECK_BUILDDIR # ------------------ # Complain if the absolute build directory name contains unusual characters m4_defun([_LT_CHECK_BUILDDIR], [case `pwd` in *\ * | *\ *) AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; esac ]) # LT_INIT([OPTIONS]) # ------------------ AC_DEFUN([LT_INIT], [AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl AC_BEFORE([$0], [LT_LANG])dnl AC_BEFORE([$0], [LT_OUTPUT])dnl AC_BEFORE([$0], [LTDL_INIT])dnl m4_require([_LT_CHECK_BUILDDIR])dnl dnl Autoconf doesn't catch unexpanded LT_ macros by default: m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 dnl unless we require an AC_DEFUNed macro: AC_REQUIRE([LTOPTIONS_VERSION])dnl AC_REQUIRE([LTSUGAR_VERSION])dnl AC_REQUIRE([LTVERSION_VERSION])dnl AC_REQUIRE([LTOBSOLETE_VERSION])dnl m4_require([_LT_PROG_LTMAIN])dnl _LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) dnl Parse OPTIONS _LT_SET_OPTIONS([$0], [$1]) # This can be used to rebuild libtool when needed LIBTOOL_DEPS="$ltmain" # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' AC_SUBST(LIBTOOL)dnl _LT_SETUP # Only expand once: m4_define([LT_INIT]) ])# LT_INIT # Old names: AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PROG_LIBTOOL], []) dnl AC_DEFUN([AM_PROG_LIBTOOL], []) # _LT_CC_BASENAME(CC) # ------------------- # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. m4_defun([_LT_CC_BASENAME], [for cc_temp in $1""; do case $cc_temp in compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` ]) # _LT_FILEUTILS_DEFAULTS # ---------------------- # It is okay to use these file commands and assume they have been set # sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. m4_defun([_LT_FILEUTILS_DEFAULTS], [: ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} ])# _LT_FILEUTILS_DEFAULTS # _LT_SETUP # --------- m4_defun([_LT_SETUP], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl _LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl dnl _LT_DECL([], [host_alias], [0], [The host system])dnl _LT_DECL([], [host], [0])dnl _LT_DECL([], [host_os], [0])dnl dnl _LT_DECL([], [build_alias], [0], [The build system])dnl _LT_DECL([], [build], [0])dnl _LT_DECL([], [build_os], [0])dnl dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl dnl AC_REQUIRE([AC_PROG_LN_S])dnl test -z "$LN_S" && LN_S="ln -s" _LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl dnl AC_REQUIRE([LT_CMD_MAX_LEN])dnl _LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl _LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl m4_require([_LT_CMD_RELOAD])dnl m4_require([_LT_CHECK_MAGIC_METHOD])dnl m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl m4_require([_LT_CMD_OLD_ARCHIVE])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_WITH_SYSROOT])dnl _LT_CONFIG_LIBTOOL_INIT([ # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi ]) if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi _LT_CHECK_OBJDIR m4_require([_LT_TAG_COMPILER])dnl case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld="$lt_cv_prog_gnu_ld" old_CC="$CC" old_CFLAGS="$CFLAGS" # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o _LT_CC_BASENAME([$compiler]) # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then _LT_PATH_MAGIC fi ;; esac # Use C for the default configuration in the libtool script LT_SUPPORTED_TAG([CC]) _LT_LANG_C_CONFIG _LT_LANG_DEFAULT_CONFIG _LT_CONFIG_COMMANDS ])# _LT_SETUP # _LT_PREPARE_SED_QUOTE_VARS # -------------------------- # Define a few sed substitution that help us do robust quoting. m4_defun([_LT_PREPARE_SED_QUOTE_VARS], [# Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\([["`\\]]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ]) # _LT_PROG_LTMAIN # --------------- # Note that this code is called both from `configure', and `config.status' # now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, # `config.status' has no value for ac_aux_dir unless we are using Automake, # so we pass a copy along to make sure it has a sensible value anyway. m4_defun([_LT_PROG_LTMAIN], [m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl _LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) ltmain="$ac_aux_dir/ltmain.sh" ])# _LT_PROG_LTMAIN ## ------------------------------------- ## ## Accumulate code for creating libtool. ## ## ------------------------------------- ## # So that we can recreate a full libtool script including additional # tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS # in macros and then make a single call at the end using the `libtool' # label. # _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) # ---------------------------------------- # Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL_INIT], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_INIT], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_INIT]) # _LT_CONFIG_LIBTOOL([COMMANDS]) # ------------------------------ # Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) # _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) # ----------------------------------------------------- m4_defun([_LT_CONFIG_SAVE_COMMANDS], [_LT_CONFIG_LIBTOOL([$1]) _LT_CONFIG_LIBTOOL_INIT([$2]) ]) # _LT_FORMAT_COMMENT([COMMENT]) # ----------------------------- # Add leading comment marks to the start of each line, and a trailing # full-stop to the whole comment if one is not present already. m4_define([_LT_FORMAT_COMMENT], [m4_ifval([$1], [ m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) )]) ## ------------------------ ## ## FIXME: Eliminate VARNAME ## ## ------------------------ ## # _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) # ------------------------------------------------------------------- # CONFIGNAME is the name given to the value in the libtool script. # VARNAME is the (base) name used in the configure script. # VALUE may be 0, 1 or 2 for a computed quote escaped value based on # VARNAME. Any other value will be used directly. m4_define([_LT_DECL], [lt_if_append_uniq([lt_decl_varnames], [$2], [, ], [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], [m4_ifval([$1], [$1], [$2])]) lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) m4_ifval([$4], [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) lt_dict_add_subkey([lt_decl_dict], [$2], [tagged?], [m4_ifval([$5], [yes], [no])])]) ]) # _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) # -------------------------------------------------------- m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) # lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_tag_varnames], [_lt_decl_filter([tagged?], [yes], $@)]) # _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) # --------------------------------------------------------- m4_define([_lt_decl_filter], [m4_case([$#], [0], [m4_fatal([$0: too few arguments: $#])], [1], [m4_fatal([$0: too few arguments: $#: $1])], [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], [lt_dict_filter([lt_decl_dict], $@)])[]dnl ]) # lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) # -------------------------------------------------- m4_define([lt_decl_quote_varnames], [_lt_decl_filter([value], [1], $@)]) # lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_dquote_varnames], [_lt_decl_filter([value], [2], $@)]) # lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_varnames_tagged], [m4_assert([$# <= 2])dnl _$0(m4_quote(m4_default([$1], [[, ]])), m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) m4_define([_lt_decl_varnames_tagged], [m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) # lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_all_varnames], [_$0(m4_quote(m4_default([$1], [[, ]])), m4_if([$2], [], m4_quote(lt_decl_varnames), m4_quote(m4_shift($@))))[]dnl ]) m4_define([_lt_decl_all_varnames], [lt_join($@, lt_decl_varnames_tagged([$1], lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl ]) # _LT_CONFIG_STATUS_DECLARE([VARNAME]) # ------------------------------------ # Quote a variable value, and forward it to `config.status' so that its # declaration there will have the same value as in `configure'. VARNAME # must have a single quote delimited value for this to work. m4_define([_LT_CONFIG_STATUS_DECLARE], [$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) # _LT_CONFIG_STATUS_DECLARATIONS # ------------------------------ # We delimit libtool config variables with single quotes, so when # we write them to config.status, we have to be sure to quote all # embedded single quotes properly. In configure, this macro expands # each variable declared with _LT_DECL (and _LT_TAGDECL) into: # # ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], [m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAGS # ---------------- # Output comment and list of tags supported by the script m4_defun([_LT_LIBTOOL_TAGS], [_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl available_tags="_LT_TAGS"dnl ]) # _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) # ----------------------------------- # Extract the dictionary values for VARNAME (optionally with TAG) and # expand to a commented shell variable setting: # # # Some comment about what VAR is for. # visible_name=$lt_internal_name m4_define([_LT_LIBTOOL_DECLARE], [_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [description])))[]dnl m4_pushdef([_libtool_name], m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), [0], [_libtool_name=[$]$1], [1], [_libtool_name=$lt_[]$1], [2], [_libtool_name=$lt_[]$1], [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl ]) # _LT_LIBTOOL_CONFIG_VARS # ----------------------- # Produce commented declarations of non-tagged libtool config variables # suitable for insertion in the LIBTOOL CONFIG section of the `libtool' # script. Tagged libtool config variables (even for the LIBTOOL CONFIG # section) are produced by _LT_LIBTOOL_TAG_VARS. m4_defun([_LT_LIBTOOL_CONFIG_VARS], [m4_foreach([_lt_var], m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAG_VARS(TAG) # ------------------------- m4_define([_LT_LIBTOOL_TAG_VARS], [m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) # _LT_TAGVAR(VARNAME, [TAGNAME]) # ------------------------------ m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) # _LT_CONFIG_COMMANDS # ------------------- # Send accumulated output to $CONFIG_STATUS. Thanks to the lists of # variables for single and double quote escaping we saved from calls # to _LT_DECL, we can put quote escaped variables declarations # into `config.status', and then the shell code to quote escape them in # for loops in `config.status'. Finally, any additional code accumulated # from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. m4_defun([_LT_CONFIG_COMMANDS], [AC_PROVIDE_IFELSE([LT_OUTPUT], dnl If the libtool generation code has been placed in $CONFIG_LT, dnl instead of duplicating it all over again into config.status, dnl then we will have config.status run $CONFIG_LT later, so it dnl needs to know what name is stored there: [AC_CONFIG_COMMANDS([libtool], [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], dnl If the libtool generation code is destined for config.status, dnl expand the accumulated commands and init code now: [AC_CONFIG_COMMANDS([libtool], [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) ])#_LT_CONFIG_COMMANDS # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], [ # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' _LT_CONFIG_STATUS_DECLARATIONS LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$[]1 _LTECHO_EOF' } # Quote evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_quote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_dquote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done _LT_OUTPUT_LIBTOOL_INIT ]) # _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) # ------------------------------------ # Generate a child script FILE with all initialization necessary to # reuse the environment learned by the parent script, and make the # file executable. If COMMENT is supplied, it is inserted after the # `#!' sequence but before initialization text begins. After this # macro, additional text can be appended to FILE to form the body of # the child script. The macro ends with non-zero status if the # file could not be fully written (such as if the disk is full). m4_ifdef([AS_INIT_GENERATED], [m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], [m4_defun([_LT_GENERATED_FILE_INIT], [m4_require([AS_PREPARE])]dnl [m4_pushdef([AS_MESSAGE_LOG_FD])]dnl [lt_write_fail=0 cat >$1 <<_ASEOF || lt_write_fail=1 #! $SHELL # Generated by $as_me. $2 SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$1 <<\_ASEOF || lt_write_fail=1 AS_SHELL_SANITIZE _AS_PREPARE exec AS_MESSAGE_FD>&1 _ASEOF test $lt_write_fail = 0 && chmod +x $1[]dnl m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT # LT_OUTPUT # --------- # This macro allows early generation of the libtool script (before # AC_OUTPUT is called), incase it is used in configure for compilation # tests. AC_DEFUN([LT_OUTPUT], [: ${CONFIG_LT=./config.lt} AC_MSG_NOTICE([creating $CONFIG_LT]) _LT_GENERATED_FILE_INIT(["$CONFIG_LT"], [# Run this file to recreate a libtool stub with the current configuration.]) cat >>"$CONFIG_LT" <<\_LTEOF lt_cl_silent=false exec AS_MESSAGE_LOG_FD>>config.log { echo AS_BOX([Running $as_me.]) } >&AS_MESSAGE_LOG_FD lt_cl_help="\ \`$as_me' creates a local libtool stub from the current configuration, for use in further configure time tests before the real libtool is generated. Usage: $[0] [[OPTIONS]] -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files Report bugs to ." lt_cl_version="\ m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) configured by $[0], generated by m4_PACKAGE_STRING. Copyright (C) 2011 Free Software Foundation, Inc. This config.lt script is free software; the Free Software Foundation gives unlimited permision to copy, distribute and modify it." while test $[#] != 0 do case $[1] in --version | --v* | -V ) echo "$lt_cl_version"; exit 0 ;; --help | --h* | -h ) echo "$lt_cl_help"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --quiet | --q* | --silent | --s* | -q ) lt_cl_silent=: ;; -*) AC_MSG_ERROR([unrecognized option: $[1] Try \`$[0] --help' for more information.]) ;; *) AC_MSG_ERROR([unrecognized argument: $[1] Try \`$[0] --help' for more information.]) ;; esac shift done if $lt_cl_silent; then exec AS_MESSAGE_FD>/dev/null fi _LTEOF cat >>"$CONFIG_LT" <<_LTEOF _LT_OUTPUT_LIBTOOL_COMMANDS_INIT _LTEOF cat >>"$CONFIG_LT" <<\_LTEOF AC_MSG_NOTICE([creating $ofile]) _LT_OUTPUT_LIBTOOL_COMMANDS AS_EXIT(0) _LTEOF chmod +x "$CONFIG_LT" # configure is writing to config.log, but config.lt does its own redirection, # appending to config.log, which fails on DOS, as config.log is still kept # open by configure. Here we exec the FD to /dev/null, effectively closing # config.log, so it can be properly (re)opened and appended to by config.lt. lt_cl_success=: test "$silent" = yes && lt_config_lt_args="$lt_config_lt_args --quiet" exec AS_MESSAGE_LOG_FD>/dev/null $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false exec AS_MESSAGE_LOG_FD>>config.log $lt_cl_success || AS_EXIT(1) ])# LT_OUTPUT # _LT_CONFIG(TAG) # --------------- # If TAG is the built-in tag, create an initial libtool script with a # default configuration from the untagged config vars. Otherwise add code # to config.status for appending the configuration named by TAG from the # matching tagged config vars. m4_defun([_LT_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_CONFIG_SAVE_COMMANDS([ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl m4_if(_LT_TAG, [C], [ # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi cfgfile="${ofile}T" trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # _LT_COPYING _LT_LIBTOOL_TAGS # ### BEGIN LIBTOOL CONFIG _LT_LIBTOOL_CONFIG_VARS _LT_LIBTOOL_TAG_VARS # ### END LIBTOOL CONFIG _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac _LT_PROG_LTMAIN # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) _LT_PROG_REPLACE_SHELLFNS mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ], [cat <<_LT_EOF >> "$ofile" dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded dnl in a comment (ie after a #). # ### BEGIN LIBTOOL TAG CONFIG: $1 _LT_LIBTOOL_TAG_VARS(_LT_TAG) # ### END LIBTOOL TAG CONFIG: $1 _LT_EOF ])dnl /m4_if ], [m4_if([$1], [], [ PACKAGE='$PACKAGE' VERSION='$VERSION' TIMESTAMP='$TIMESTAMP' RM='$RM' ofile='$ofile'], []) ])dnl /_LT_CONFIG_SAVE_COMMANDS ])# _LT_CONFIG # LT_SUPPORTED_TAG(TAG) # --------------------- # Trace this macro to discover what tags are supported by the libtool # --tag option, using: # autoconf --trace 'LT_SUPPORTED_TAG:$1' AC_DEFUN([LT_SUPPORTED_TAG], []) # C support is built-in for now m4_define([_LT_LANG_C_enabled], []) m4_define([_LT_TAGS], []) # LT_LANG(LANG) # ------------- # Enable libtool support for the given language if not already enabled. AC_DEFUN([LT_LANG], [AC_BEFORE([$0], [LT_OUTPUT])dnl m4_case([$1], [C], [_LT_LANG(C)], [C++], [_LT_LANG(CXX)], [Go], [_LT_LANG(GO)], [Java], [_LT_LANG(GCJ)], [Fortran 77], [_LT_LANG(F77)], [Fortran], [_LT_LANG(FC)], [Windows Resource], [_LT_LANG(RC)], [m4_ifdef([_LT_LANG_]$1[_CONFIG], [_LT_LANG($1)], [m4_fatal([$0: unsupported language: "$1"])])])dnl ])# LT_LANG # _LT_LANG(LANGNAME) # ------------------ m4_defun([_LT_LANG], [m4_ifdef([_LT_LANG_]$1[_enabled], [], [LT_SUPPORTED_TAG([$1])dnl m4_append([_LT_TAGS], [$1 ])dnl m4_define([_LT_LANG_]$1[_enabled], [])dnl _LT_LANG_$1_CONFIG($1)])dnl ])# _LT_LANG m4_ifndef([AC_PROG_GO], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_GO. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_GO], [AC_LANG_PUSH(Go)dnl AC_ARG_VAR([GOC], [Go compiler command])dnl AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl _AC_ARG_VAR_LDFLAGS()dnl AC_CHECK_TOOL(GOC, gccgo) if test -z "$GOC"; then if test -n "$ac_tool_prefix"; then AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) fi fi if test -z "$GOC"; then AC_CHECK_PROG(GOC, gccgo, gccgo, false) fi ])#m4_defun ])#m4_ifndef # _LT_LANG_DEFAULT_CONFIG # ----------------------- m4_defun([_LT_LANG_DEFAULT_CONFIG], [AC_PROVIDE_IFELSE([AC_PROG_CXX], [LT_LANG(CXX)], [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) AC_PROVIDE_IFELSE([AC_PROG_F77], [LT_LANG(F77)], [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) AC_PROVIDE_IFELSE([AC_PROG_FC], [LT_LANG(FC)], [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal dnl pulling things in needlessly. AC_PROVIDE_IFELSE([AC_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([LT_PROG_GCJ], [LT_LANG(GCJ)], [m4_ifdef([AC_PROG_GCJ], [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([A][M_PROG_GCJ], [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([LT_PROG_GCJ], [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) AC_PROVIDE_IFELSE([AC_PROG_GO], [LT_LANG(GO)], [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) AC_PROVIDE_IFELSE([LT_PROG_RC], [LT_LANG(RC)], [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) ])# _LT_LANG_DEFAULT_CONFIG # Obsolete macros: AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_CXX], []) dnl AC_DEFUN([AC_LIBTOOL_F77], []) dnl AC_DEFUN([AC_LIBTOOL_FC], []) dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) dnl AC_DEFUN([AC_LIBTOOL_RC], []) # _LT_TAG_COMPILER # ---------------- m4_defun([_LT_TAG_COMPILER], [AC_REQUIRE([AC_PROG_CC])dnl _LT_DECL([LTCC], [CC], [1], [A C compiler])dnl _LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl _LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl _LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC ])# _LT_TAG_COMPILER # _LT_COMPILER_BOILERPLATE # ------------------------ # Check for compiler boilerplate output or warnings with # the simple compiler test code. m4_defun([_LT_COMPILER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ])# _LT_COMPILER_BOILERPLATE # _LT_LINKER_BOILERPLATE # ---------------------- # Check for linker boilerplate output or warnings with # the simple link test code. m4_defun([_LT_LINKER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ])# _LT_LINKER_BOILERPLATE # _LT_REQUIRED_DARWIN_CHECKS # ------------------------- m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ case $host_os in rhapsody* | darwin*) AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) AC_CHECK_TOOL([LIPO], [lipo], [:]) AC_CHECK_TOOL([OTOOL], [otool], [:]) AC_CHECK_TOOL([OTOOL64], [otool64], [:]) _LT_DECL([], [DSYMUTIL], [1], [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) _LT_DECL([], [NMEDIT], [1], [Tool to change global to local symbols on Mac OS X]) _LT_DECL([], [LIPO], [1], [Tool to manipulate fat objects and archives on Mac OS X]) _LT_DECL([], [OTOOL], [1], [ldd/readelf like tool for Mach-O binaries on Mac OS X]) _LT_DECL([], [OTOOL64], [1], [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], [lt_cv_apple_cc_single_mod=no if test -z "${LT_MULTI_MODULE}"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test $_lt_result -eq 0; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -rf libconftest.dylib* rm -f conftest.* fi]) AC_CACHE_CHECK([for -exported_symbols_list linker flag], [lt_cv_ld_exported_symbols_list], [lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [lt_cv_ld_exported_symbols_list=yes], [lt_cv_ld_exported_symbols_list=no]) LDFLAGS="$save_LDFLAGS" ]) AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], [lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then lt_cv_ld_force_load=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM ]) case $host_os in rhapsody* | darwin1.[[012]]) _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; 10.[[012]]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test "$lt_cv_apple_cc_single_mod" = "yes"; then _lt_dar_single_mod='$single_module' fi if test "$lt_cv_ld_exported_symbols_list" = "yes"; then _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' fi if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ]) # _LT_DARWIN_LINKER_FEATURES([TAG]) # --------------------------------- # Checks for linker and compiler features on darwin m4_defun([_LT_DARWIN_LINKER_FEATURES], [ m4_require([_LT_REQUIRED_DARWIN_CHECKS]) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported if test "$lt_cv_ld_force_load" = "yes"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) else _LT_TAGVAR(whole_archive_flag_spec, $1)='' fi _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" m4_if([$1], [CXX], [ if test "$lt_cv_apple_cc_single_mod" != "yes"; then _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" fi ],[]) else _LT_TAGVAR(ld_shlibs, $1)=no fi ]) # _LT_SYS_MODULE_PATH_AIX([TAGNAME]) # ---------------------------------- # Links a minimal program and checks the executable # for the system default hardcoded library path. In most cases, # this is /usr/lib:/lib, but when the MPI compilers are used # the location of the communication and MPI libs are included too. # If we don't find anything, use the default library path according # to the aix ld manual. # Store the results from the different compilers for each TAGNAME. # Allow to override them for all tags through lt_cv_aix_libpath. m4_defun([_LT_SYS_MODULE_PATH_AIX], [m4_require([_LT_DECL_SED])dnl if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ lt_aix_libpath_sed='[ /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }]' _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi],[]) if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib" fi ]) aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) fi ])# _LT_SYS_MODULE_PATH_AIX # _LT_SHELL_INIT(ARG) # ------------------- m4_define([_LT_SHELL_INIT], [m4_divert_text([M4SH-INIT], [$1 ])])# _LT_SHELL_INIT # _LT_PROG_ECHO_BACKSLASH # ----------------------- # Find how we can fake an echo command that does not interpret backslash. # In particular, with Autoconf 2.60 or later we add some code to the start # of the generated configure script which will find a shell with a builtin # printf (which we can use as an echo command). m4_defun([_LT_PROG_ECHO_BACKSLASH], [ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO AC_MSG_CHECKING([how to print strings]) # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $[]1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } case "$ECHO" in printf*) AC_MSG_RESULT([printf]) ;; print*) AC_MSG_RESULT([print -r]) ;; *) AC_MSG_RESULT([cat]) ;; esac m4_ifdef([_AS_DETECT_SUGGESTED], [_AS_DETECT_SUGGESTED([ test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test "X`printf %s $ECHO`" = "X$ECHO" \ || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) _LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) ])# _LT_PROG_ECHO_BACKSLASH # _LT_WITH_SYSROOT # ---------------- AC_DEFUN([_LT_WITH_SYSROOT], [AC_MSG_CHECKING([for sysroot]) AC_ARG_WITH([sysroot], [ --with-sysroot[=DIR] Search for dependent libraries within DIR (or the compiler's sysroot if not specified).], [], [with_sysroot=no]) dnl lt_sysroot will always be passed unquoted. We quote it here dnl in case the user passed a directory name. lt_sysroot= case ${with_sysroot} in #( yes) if test "$GCC" = yes; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) AC_MSG_RESULT([${with_sysroot}]) AC_MSG_ERROR([The sysroot must be an absolute path.]) ;; esac AC_MSG_RESULT([${lt_sysroot:-no}]) _LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl [dependent libraries, and in which our libraries should be installed.])]) # _LT_ENABLE_LOCK # --------------- m4_defun([_LT_ENABLE_LOCK], [AC_ARG_ENABLE([libtool-lock], [AS_HELP_STRING([--disable-libtool-lock], [avoid locking (might break parallel builds)])]) test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE="32" ;; *ELF-64*) HPUX_IA64_MODE="64" ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out which ABI we are using. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then if test "$lt_cv_prog_gnu_ld" = yes; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) case `/usr/bin/file conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; *) LD="${LD-ld} -m elf_i386" ;; esac ;; powerpc64le-*) LD="${LD-ld} -m elf32lppclinux" ;; powerpc64-*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; powerpcle-*) LD="${LD-ld} -m elf64lppc" ;; powerpc-*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -belf" AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, [AC_LANG_PUSH(C) AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) AC_LANG_POP]) if test x"$lt_cv_cc_needs_belf" != x"yes"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS="$SAVE_CFLAGS" fi ;; *-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD="${LD-ld}_sol2" fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks="$enable_libtool_lock" ])# _LT_ENABLE_LOCK # _LT_PROG_AR # ----------- m4_defun([_LT_PROG_AR], [AC_CHECK_TOOLS(AR, [ar], false) : ${AR=ar} : ${AR_FLAGS=cru} _LT_DECL([], [AR], [1], [The archiver]) _LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], [lt_cv_ar_at_file=no AC_COMPILE_IFELSE([AC_LANG_PROGRAM], [echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([lt_ar_try]) if test "$ac_status" -eq 0; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a AC_TRY_EVAL([lt_ar_try]) if test "$ac_status" -ne 0; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a ]) ]) if test "x$lt_cv_ar_at_file" = xno; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi _LT_DECL([], [archiver_list_spec], [1], [How to feed a file listing to the archiver]) ])# _LT_PROG_AR # _LT_CMD_OLD_ARCHIVE # ------------------- m4_defun([_LT_CMD_OLD_ARCHIVE], [_LT_PROG_AR AC_CHECK_TOOL(STRIP, strip, :) test -z "$STRIP" && STRIP=: _LT_DECL([], [STRIP], [1], [A symbol stripping program]) AC_CHECK_TOOL(RANLIB, ranlib, :) test -z "$RANLIB" && RANLIB=: _LT_DECL([], [RANLIB], [1], [Commands used to install an old-style archive]) # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac _LT_DECL([], [old_postinstall_cmds], [2]) _LT_DECL([], [old_postuninstall_cmds], [2]) _LT_TAGDECL([], [old_archive_cmds], [2], [Commands used to build an old-style archive]) _LT_DECL([], [lock_old_archive_extraction], [0], [Whether to use a lock for old archive extraction]) ])# _LT_CMD_OLD_ARCHIVE # _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------------------- # Check whether the given compiler option works AC_DEFUN([_LT_COMPILER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$3" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi fi $RM conftest* ]) if test x"[$]$2" = xyes; then m4_if([$5], , :, [$5]) else m4_if([$6], , :, [$6]) fi ])# _LT_COMPILER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) # _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------- # Check whether the given linker option works AC_DEFUN([_LT_LINKER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $3" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&AS_MESSAGE_LOG_FD $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi else $2=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" ]) if test x"[$]$2" = xyes; then m4_if([$4], , :, [$4]) else m4_if([$5], , :, [$5]) fi ])# _LT_LINKER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) # LT_CMD_MAX_LEN #--------------- AC_DEFUN([LT_CMD_MAX_LEN], [AC_REQUIRE([AC_CANONICAL_HOST])dnl # find the maximum length of command line arguments AC_MSG_CHECKING([the maximum length of command line arguments]) AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl i=0 teststring="ABCD" case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len" && \ test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8 ; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test $i != 17 # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac ]) if test -n $lt_cv_sys_max_cmd_len ; then AC_MSG_RESULT($lt_cv_sys_max_cmd_len) else AC_MSG_RESULT(none) fi max_cmd_len=$lt_cv_sys_max_cmd_len _LT_DECL([], [max_cmd_len], [0], [What is the maximum length of a command?]) ])# LT_CMD_MAX_LEN # Old name: AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) # _LT_HEADER_DLFCN # ---------------- m4_defun([_LT_HEADER_DLFCN], [AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl ])# _LT_HEADER_DLFCN # _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, # ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) # ---------------------------------------------------------------- m4_defun([_LT_TRY_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test "$cross_compiling" = yes; then : [$4] else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF [#line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; }] _LT_EOF if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) $1 ;; x$lt_dlneed_uscore) $2 ;; x$lt_dlunknown|x*) $3 ;; esac else : # compilation failed $3 fi fi rm -fr conftest* ])# _LT_TRY_DLOPEN_SELF # LT_SYS_DLOPEN_SELF # ------------------ AC_DEFUN([LT_SYS_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test "x$enable_dlopen" != xyes; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen="load_add_on" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen="LoadLibrary" lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen="dlopen" lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ lt_cv_dlopen="dyld" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ]) ;; *) AC_CHECK_FUNC([shl_load], [lt_cv_dlopen="shl_load"], [AC_CHECK_LIB([dld], [shl_load], [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], [AC_CHECK_FUNC([dlopen], [lt_cv_dlopen="dlopen"], [AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], [AC_CHECK_LIB([svld], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], [AC_CHECK_LIB([dld], [dld_link], [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) ]) ]) ]) ]) ]) ;; esac if test "x$lt_cv_dlopen" != xno; then enable_dlopen=yes else enable_dlopen=no fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS="$CPPFLAGS" test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS="$LDFLAGS" wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS="$LIBS" LIBS="$lt_cv_dlopen_libs $LIBS" AC_CACHE_CHECK([whether a program can dlopen itself], lt_cv_dlopen_self, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) ]) if test "x$lt_cv_dlopen_self" = xyes; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" AC_CACHE_CHECK([whether a statically linked program can dlopen itself], lt_cv_dlopen_self_static, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) ]) fi CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi _LT_DECL([dlopen_support], [enable_dlopen], [0], [Whether dlopen is supported]) _LT_DECL([dlopen_self], [enable_dlopen_self], [0], [Whether dlopen of programs is supported]) _LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], [Whether dlopen of statically linked programs is supported]) ])# LT_SYS_DLOPEN_SELF # Old name: AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) # _LT_COMPILER_C_O([TAGNAME]) # --------------------------- # Check to see if options -c and -o are simultaneously supported by compiler. # This macro does not hard code the compiler like AC_PROG_CC_C_O. m4_defun([_LT_COMPILER_C_O], [m4_require([_LT_DECL_SED])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes fi fi chmod u+w . 2>&AS_MESSAGE_LOG_FD $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* ]) _LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], [Does compiler simultaneously support -c and -o options?]) ])# _LT_COMPILER_C_O # _LT_COMPILER_FILE_LOCKS([TAGNAME]) # ---------------------------------- # Check to see if we can do hard links to lock some files if needed m4_defun([_LT_COMPILER_FILE_LOCKS], [m4_require([_LT_ENABLE_LOCK])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_COMPILER_C_O([$1]) hard_links="nottested" if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user AC_MSG_CHECKING([if we can lock with hard links]) hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no AC_MSG_RESULT([$hard_links]) if test "$hard_links" = no; then AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) need_locks=warn fi else need_locks=no fi _LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) ])# _LT_COMPILER_FILE_LOCKS # _LT_CHECK_OBJDIR # ---------------- m4_defun([_LT_CHECK_OBJDIR], [AC_CACHE_CHECK([for objdir], [lt_cv_objdir], [rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null]) objdir=$lt_cv_objdir _LT_DECL([], [objdir], [0], [The name of the directory that contains temporary libtool files])dnl m4_pattern_allow([LT_OBJDIR])dnl AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", [Define to the sub-directory in which libtool stores uninstalled libraries.]) ])# _LT_CHECK_OBJDIR # _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) # -------------------------------------- # Check hardcoding attributes. m4_defun([_LT_LINKER_HARDCODE_LIBPATH], [AC_MSG_CHECKING([how to hardcode library paths into programs]) _LT_TAGVAR(hardcode_action, $1)= if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || test -n "$_LT_TAGVAR(runpath_var, $1)" || test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then # We can hardcode non-existent directories. if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then # Linking always hardcodes the temporary library directory. _LT_TAGVAR(hardcode_action, $1)=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. _LT_TAGVAR(hardcode_action, $1)=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. _LT_TAGVAR(hardcode_action, $1)=unsupported fi AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi _LT_TAGDECL([], [hardcode_action], [0], [How to hardcode a shared library path into an executable]) ])# _LT_LINKER_HARDCODE_LIBPATH # _LT_CMD_STRIPLIB # ---------------- m4_defun([_LT_CMD_STRIPLIB], [m4_require([_LT_DECL_EGREP]) striplib= old_striplib= AC_MSG_CHECKING([whether stripping libraries is possible]) if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" AC_MSG_RESULT([yes]) else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP" ; then striplib="$STRIP -x" old_striplib="$STRIP -S" AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi ;; *) AC_MSG_RESULT([no]) ;; esac fi _LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) _LT_DECL([], [striplib], [1]) ])# _LT_CMD_STRIPLIB # _LT_SYS_DYNAMIC_LINKER([TAG]) # ----------------------------- # PORTME Fill in your ld.so characteristics m4_defun([_LT_SYS_DYNAMIC_LINKER], [AC_REQUIRE([AC_CANONICAL_HOST])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_OBJDUMP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl AC_MSG_CHECKING([dynamic linker characteristics]) m4_if([$1], [], [ if test "$GCC" = yes; then case $host_os in darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; *) lt_awk_arg="/^libraries:/" ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;; *) lt_sed_strip_eq="s,=/,/,g" ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary. lt_tmp_lt_search_path_spec= lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path/$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" else test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS=" "; FS="/|\n";} { lt_foo=""; lt_count=0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo="/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[[lt_foo]]++; } if (lt_freq[[lt_foo]] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's,/\([[A-Za-z]]:\),\1,g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi]) library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix[[4-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[[01]] | aix4.[[01]].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[[45]]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' library_names_spec='${libname}.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec="$LIB" if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[[23]].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[[01]]* | freebsdelf3.[[01]]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=yes sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[[3-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], [lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], [lt_cv_shlibpath_overrides_runpath=yes])]) LDFLAGS=$save_LDFLAGS libdir=$save_libdir ]) shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[[89]] | openbsd2.[[89]].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac AC_MSG_RESULT([$dynamic_linker]) test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi _LT_DECL([], [variables_saved_for_relink], [1], [Variables whose values should be saved in libtool wrapper scripts and restored at link time]) _LT_DECL([], [need_lib_prefix], [0], [Do we need the "lib" prefix for modules?]) _LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) _LT_DECL([], [version_type], [0], [Library versioning type]) _LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) _LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) _LT_DECL([], [shlibpath_overrides_runpath], [0], [Is shlibpath searched before the hard-coded library search path?]) _LT_DECL([], [libname_spec], [1], [Format of library name prefix]) _LT_DECL([], [library_names_spec], [1], [[List of archive names. First name is the real one, the rest are links. The last name is the one that the linker finds with -lNAME]]) _LT_DECL([], [soname_spec], [1], [[The coded name of the library, if different from the real name]]) _LT_DECL([], [install_override_mode], [1], [Permission mode override for installation of shared libraries]) _LT_DECL([], [postinstall_cmds], [2], [Command to use after installation of a shared archive]) _LT_DECL([], [postuninstall_cmds], [2], [Command to use after uninstallation of a shared archive]) _LT_DECL([], [finish_cmds], [2], [Commands used to finish a libtool library installation in a directory]) _LT_DECL([], [finish_eval], [1], [[As "finish_cmds", except a single script fragment to be evaled but not shown]]) _LT_DECL([], [hardcode_into_libs], [0], [Whether we should hardcode library paths into libraries]) _LT_DECL([], [sys_lib_search_path_spec], [2], [Compile-time system search path for libraries]) _LT_DECL([], [sys_lib_dlsearch_path_spec], [2], [Run-time system search path for libraries]) ])# _LT_SYS_DYNAMIC_LINKER # _LT_PATH_TOOL_PREFIX(TOOL) # -------------------------- # find a file program which can recognize shared library AC_DEFUN([_LT_PATH_TOOL_PREFIX], [m4_require([_LT_DECL_EGREP])dnl AC_MSG_CHECKING([for $1]) AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, [case $MAGIC_CMD in [[\\/*] | ?:[\\/]*]) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR dnl $ac_dummy forces splitting on constant user-supplied paths. dnl POSIX.2 word splitting is done only on the output of word expansions, dnl not every word. This closes a longstanding sh security hole. ac_dummy="m4_if([$2], , $PATH, [$2])" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$1; then lt_cv_path_MAGIC_CMD="$ac_dir/$1" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac]) MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then AC_MSG_RESULT($MAGIC_CMD) else AC_MSG_RESULT(no) fi _LT_DECL([], [MAGIC_CMD], [0], [Used to examine libraries when file_magic_cmd begins with "file"])dnl ])# _LT_PATH_TOOL_PREFIX # Old name: AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) # _LT_PATH_MAGIC # -------------- # find a file program which can recognize a shared library m4_defun([_LT_PATH_MAGIC], [_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) else MAGIC_CMD=: fi fi ])# _LT_PATH_MAGIC # LT_PATH_LD # ---------- # find the pathname to the GNU or non-GNU linker AC_DEFUN([LT_PATH_LD], [AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PROG_ECHO_BACKSLASH])dnl AC_ARG_WITH([gnu-ld], [AS_HELP_STRING([--with-gnu-ld], [assume the C compiler uses GNU ld @<:@default=no@:>@])], [test "$withval" = no || with_gnu_ld=yes], [with_gnu_ld=no])dnl ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by $CC]) case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [[\\/]]* | ?:[[\\/]]*) re_direlt='/[[^/]][[^/]]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL(lt_cv_path_LD, [if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[[3-9]]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; esac ]) file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown _LT_DECL([], [deplibs_check_method], [1], [Method to check whether dependent libraries are shared objects]) _LT_DECL([], [file_magic_cmd], [1], [Command to use when deplibs_check_method = "file_magic"]) _LT_DECL([], [file_magic_glob], [1], [How to find potential files when deplibs_check_method = "file_magic"]) _LT_DECL([], [want_nocaseglob], [1], [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) ])# _LT_CHECK_MAGIC_METHOD # LT_PATH_NM # ---------- # find the pathname to a BSD- or MS-compatible name lister AC_DEFUN([LT_PATH_NM], [AC_REQUIRE([AC_PROG_CC])dnl AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, [if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM="$NM" else lt_nm_to_check="${ac_tool_prefix}nm" if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. tmp_nm="$ac_dir/$lt_tmp_nm" if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then # Check to see if the nm accepts a BSD-compat flag. # Adding the `sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS="$lt_save_ifs" done : ${lt_cv_path_NM=no} fi]) if test "$lt_cv_path_NM" != "no"; then NM="$lt_cv_path_NM" else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols" ;; *) DUMPBIN=: ;; esac fi AC_SUBST([DUMPBIN]) if test "$DUMPBIN" != ":"; then NM="$DUMPBIN" fi fi test -z "$NM" && NM=nm AC_SUBST([NM]) _LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], [lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) cat conftest.out >&AS_MESSAGE_LOG_FD if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest*]) ])# LT_PATH_NM # Old names: AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_PROG_NM], []) dnl AC_DEFUN([AC_PROG_NM], []) # _LT_CHECK_SHAREDLIB_FROM_LINKLIB # -------------------------------- # how to determine the name of the shared library # associated with a specific link library. # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], [m4_require([_LT_DECL_EGREP]) m4_require([_LT_DECL_OBJDUMP]) m4_require([_LT_DECL_DLLTOOL]) AC_CACHE_CHECK([how to associate runtime and link libraries], lt_cv_sharedlib_from_linklib_cmd, [lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh # decide which to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd="$ECHO" ;; esac ]) sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO _LT_DECL([], [sharedlib_from_linklib_cmd], [1], [Command to associate shared and link libraries]) ])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB # _LT_PATH_MANIFEST_TOOL # ---------------------- # locate the manifest tool m4_defun([_LT_PATH_MANIFEST_TOOL], [AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], [lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&AS_MESSAGE_LOG_FD if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest*]) if test "x$lt_cv_path_mainfest_tool" != xyes; then MANIFEST_TOOL=: fi _LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl ])# _LT_PATH_MANIFEST_TOOL # LT_LIB_M # -------- # check for math library AC_DEFUN([LT_LIB_M], [AC_REQUIRE([AC_CANONICAL_HOST])dnl LIBM= case $host in *-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) # These system don't have libm, or don't need it ;; *-ncr-sysv4.3*) AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") ;; *) AC_CHECK_LIB(m, cos, LIBM="-lm") ;; esac AC_SUBST([LIBM]) ])# LT_LIB_M # Old name: AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_CHECK_LIBM], []) # _LT_COMPILER_NO_RTTI([TAGNAME]) # ------------------------------- m4_defun([_LT_COMPILER_NO_RTTI], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= if test "$GCC" = yes; then case $cc_basename in nvcc*) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; *) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; esac _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], lt_cv_prog_compiler_rtti_exceptions, [-fno-rtti -fno-exceptions], [], [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) fi _LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], [Compiler flag to turn off builtin functions]) ])# _LT_COMPILER_NO_RTTI # _LT_CMD_GLOBAL_SYMBOLS # ---------------------- m4_defun([_LT_CMD_GLOBAL_SYMBOLS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([LT_PATH_NM])dnl AC_REQUIRE([LT_PATH_LD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_TAG_COMPILER])dnl # Check for command to grab the raw symbol name followed by C symbol from nm. AC_MSG_CHECKING([command to parse $NM output from $compiler object]) AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [ # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[[BCDEGRST]]' # Regexp to match symbols that can be accessed directly from C. sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[[BCDT]]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[[ABCDGISTW]]' ;; hpux*) if test "$host_cpu" = ia64; then symcode='[[ABCDEGRST]]' fi ;; irix* | nonstopux*) symcode='[[BCDEGRST]]' ;; osf*) symcode='[[BCDEGQRST]]' ;; solaris*) symcode='[[BDRT]]' ;; sco3.2v5*) symcode='[[DT]]' ;; sysv4.2uw2*) symcode='[[DT]]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[[ABDT]]' ;; sysv4) symcode='[[DFNSTU]]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[[ABCDGIRSTW]]' ;; esac # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function # and D for any global variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ " {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ " s[1]~/^[@?]/{print s[1], s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx]" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. nlist=conftest.nm if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT@&t@_DLSYM_CONST #elif defined(__osf__) /* This system does not cope well with relocations in const data. */ # define LT@&t@_DLSYM_CONST #else # define LT@&t@_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT@&t@_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[[]] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD fi else echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test "$pipe_works" = yes; then break else lt_cv_sys_global_symbol_pipe= fi done ]) if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then AC_MSG_RESULT(failed) else AC_MSG_RESULT(ok) fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then nm_file_list_spec='@' fi _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], [Take the output of nm and produce a listing of raw symbols and C names]) _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], [Transform the output of nm in a proper C declaration]) _LT_DECL([global_symbol_to_c_name_address], [lt_cv_sys_global_symbol_to_c_name_address], [1], [Transform the output of nm in a C name address pair]) _LT_DECL([global_symbol_to_c_name_address_lib_prefix], [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], [Transform the output of nm in a C name address pair when lib prefix is needed]) _LT_DECL([], [nm_file_list_spec], [1], [Specify filename containing input files for $NM]) ]) # _LT_CMD_GLOBAL_SYMBOLS # _LT_COMPILER_PIC([TAGNAME]) # --------------------------- m4_defun([_LT_COMPILER_PIC], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_wl, $1)= _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)= m4_if([$1], [CXX], [ # C++ specific cases for pic, static, wl, etc. if test "$GXX" = yes; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac else case $host_os in aix[[4-9]]*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; dgux*) case $cc_basename in ec++*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; ghcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; freebsd* | dragonfly*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' if test "$host_cpu" != ia64; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' fi ;; aCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # KAI C++ Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64 which still supported -KPIC. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL 8.0, 9.0 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' ;; *) ;; esac ;; netbsd* | netbsdelf*-gnu) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; cxx*) # Digital/Compaq C++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; lcc*) # Lucid _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ], [ if test "$GCC" = yes; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; hpux9* | hpux10* | hpux11*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC (with -KPIC) is the default. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in # old Intel for x86_64 which still supported -KPIC. ecc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # Lahey Fortran 8.1. lf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' ;; nagfor*) # NAG Fortran compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; ccc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All Alpha code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='' ;; *Sun\ F* | *Sun*Fortran*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ;; *Intel*\ [[CF]]*Compiler*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; *Portland\ Group*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; esac ;; newsos6) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All OSF/1 code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; rdos*) _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; solaris*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; *) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; esac ;; sunos4*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; unicos*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; uts4*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ]) case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" ;; esac AC_CACHE_CHECK([for $compiler option to produce PIC], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) _LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) # # Check to make sure the PIC flag actually works. # if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in "" | " "*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; esac], [_LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) fi _LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], [Additional compiler flags for building library objects]) _LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], [How to pass a linker flag through the compiler]) # # Check to make sure the static flag actually works. # wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" _LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), $lt_tmp_static_flag, [], [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) _LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], [Compiler flag to prevent dynamic linking]) ])# _LT_COMPILER_PIC # _LT_LINKER_SHLIBS([TAGNAME]) # ---------------------------- # See if the linker supports building shared libraries. m4_defun([_LT_LINKER_SHLIBS], [AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) m4_if([$1], [CXX], [ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] case $host_os in aix[[4-9]]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm # Also, AIX nm treats weak defined symbols like other global defined # symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi ;; pw32*) _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" ;; cygwin* | mingw* | cegcc*) case $cc_basename in cl*) _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] ;; esac ;; linux* | k*bsd*-gnu | gnu*) _LT_TAGVAR(link_all_deplibs, $1)=no ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac ], [ runpath_var= _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_cmds, $1)= _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(old_archive_from_new_cmds, $1)= _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= _LT_TAGVAR(thread_safe_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list _LT_TAGVAR(include_expsyms, $1)= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. dnl Note also adjust exclude_expsyms for C++ above. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; linux* | k*bsd*-gnu | gnu*) _LT_TAGVAR(link_all_deplibs, $1)=no ;; esac _LT_TAGVAR(ld_shlibs, $1)=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test "$with_gnu_ld" = yes; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test "$lt_use_gnu_ld_interface" = yes; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi supports_anon_versioning=no case `$LD -v 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[[3-9]]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test "$host_os" = linux-dietlibc; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test "$tmp_diet" = no then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 _LT_TAGVAR(whole_archive_flag_spec, $1)= tmp_sharedflag='--shared' ;; xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi case $cc_basename in xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; sunos4*) _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then runpath_var= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. _LT_TAGVAR(hardcode_minus_L, $1)=yes if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. _LT_TAGVAR(hardcode_direct, $1)=unsupported fi ;; aix[[4-9]]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm # Also, AIX nm treats weak defined symbols like other global # defined symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' if test "$GCC" = yes; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi _LT_TAGVAR(link_all_deplibs, $1)=no else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. _LT_TAGVAR(always_export_symbols, $1)=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; bsdi[[45]]*) _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl*) # Native MSVC _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' # FIXME: Should let the user specify the lib program. _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; hpux9*) if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; hpux10*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test "$with_gnu_ld" = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes fi ;; hpux11*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) m4_if($1, [], [ # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) _LT_LINKER_OPTION([if $CC understands -b], _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) ;; esac fi if test "$with_gnu_ld" = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], [lt_cv_irix_exported_symbol], [save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" AC_LINK_IFELSE( [AC_LANG_SOURCE( [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], [C++], [[int foo (void) { return 0; }]], [Fortran 77], [[ subroutine foo end]], [Fortran], [[ subroutine foo end]])])], [lt_cv_irix_exported_symbol=yes], [lt_cv_irix_exported_symbol=no]) LDFLAGS="$save_LDFLAGS"]) if test "$lt_cv_irix_exported_symbol" = yes; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' fi else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes _LT_TAGVAR(link_all_deplibs, $1)=yes ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; newsos6) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *nto* | *qnx*) ;; openbsd*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' else case $host_os in openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' ;; esac fi else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; solaris*) _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' if test "$GCC" = yes; then wlarc='${wl}' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='${wl}' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. GCC discards it without `$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test "$GCC" = yes; then _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' else _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' fi ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes ;; sunos4*) if test "x$host_vendor" = xsequent; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4) case $host_vendor in sni) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' _LT_TAGVAR(hardcode_direct, $1)=no ;; motorola) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4.3*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes _LT_TAGVAR(ld_shlibs, $1)=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(ld_shlibs, $1)=no ;; esac if test x$host_vendor = xsni; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' ;; esac fi fi ]) AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no _LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld _LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl _LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl _LT_DECL([], [extract_expsyms_cmds], [2], [The commands to extract the exported symbol list from a shared archive]) # # Do we need to explicitly link libc? # case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in x|xyes) # Assume -lc should be added _LT_TAGVAR(archive_cmds_need_lc, $1)=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $_LT_TAGVAR(archive_cmds, $1) in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. AC_CACHE_CHECK([whether -lc should be explicitly linked in], [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), [$RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if AC_TRY_EVAL(ac_compile) 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) _LT_TAGVAR(allow_undefined_flag, $1)= if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) then lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no else lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes fi _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* ]) _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) ;; esac fi ;; esac _LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], [Whether or not to add -lc for building shared libraries]) _LT_TAGDECL([allow_libtool_libs_with_static_runtimes], [enable_shared_with_static_runtimes], [0], [Whether or not to disallow shared libs when runtime libs are static]) _LT_TAGDECL([], [export_dynamic_flag_spec], [1], [Compiler flag to allow reflexive dlopens]) _LT_TAGDECL([], [whole_archive_flag_spec], [1], [Compiler flag to generate shared objects directly from archives]) _LT_TAGDECL([], [compiler_needs_object], [1], [Whether the compiler copes with passing no objects directly]) _LT_TAGDECL([], [old_archive_from_new_cmds], [2], [Create an old-style archive from a shared archive]) _LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], [Create a temporary old-style archive to link instead of a shared archive]) _LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) _LT_TAGDECL([], [archive_expsym_cmds], [2]) _LT_TAGDECL([], [module_cmds], [2], [Commands used to build a loadable module if different from building a shared archive.]) _LT_TAGDECL([], [module_expsym_cmds], [2]) _LT_TAGDECL([], [with_gnu_ld], [1], [Whether we are building with GNU ld or not]) _LT_TAGDECL([], [allow_undefined_flag], [1], [Flag that allows shared libraries with undefined symbols to be built]) _LT_TAGDECL([], [no_undefined_flag], [1], [Flag that enforces no undefined symbols]) _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], [Flag to hardcode $libdir into a binary during linking. This must work even if $libdir does not exist]) _LT_TAGDECL([], [hardcode_libdir_separator], [1], [Whether we need a single "-rpath" flag with a separated argument]) _LT_TAGDECL([], [hardcode_direct], [0], [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_direct_absolute], [0], [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the resulting binary and the resulting library dependency is "absolute", i.e impossible to change by setting ${shlibpath_var} if the library is relocated]) _LT_TAGDECL([], [hardcode_minus_L], [0], [Set to "yes" if using the -LDIR flag during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_shlibpath_var], [0], [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_automatic], [0], [Set to "yes" if building a shared library automatically hardcodes DIR into the library and all subsequent libraries and executables linked against it]) _LT_TAGDECL([], [inherit_rpath], [0], [Set to yes if linker adds runtime paths of dependent libraries to runtime path list]) _LT_TAGDECL([], [link_all_deplibs], [0], [Whether libtool must link a program against all its dependency libraries]) _LT_TAGDECL([], [always_export_symbols], [0], [Set to "yes" if exported symbols are required]) _LT_TAGDECL([], [export_symbols_cmds], [2], [The commands to list exported symbols]) _LT_TAGDECL([], [exclude_expsyms], [1], [Symbols that should not be listed in the preloaded symbols]) _LT_TAGDECL([], [include_expsyms], [1], [Symbols that must always be exported]) _LT_TAGDECL([], [prelink_cmds], [2], [Commands necessary for linking programs (against libraries) with templates]) _LT_TAGDECL([], [postlink_cmds], [2], [Commands necessary for finishing linking programs]) _LT_TAGDECL([], [file_list_spec], [1], [Specify filename containing input files]) dnl FIXME: Not yet implemented dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], dnl [Compiler flag to generate thread safe objects]) ])# _LT_LINKER_SHLIBS # _LT_LANG_C_CONFIG([TAG]) # ------------------------ # Ensure that the configuration variables for a C compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to `libtool'. m4_defun([_LT_LANG_C_CONFIG], [m4_require([_LT_DECL_EGREP])dnl lt_save_CC="$CC" AC_LANG_PUSH(C) # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' _LT_TAG_COMPILER # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) LT_SYS_DLOPEN_SELF _LT_CMD_STRIPLIB # Report which library types will actually be built AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_CONFIG($1) fi AC_LANG_POP CC="$lt_save_CC" ])# _LT_LANG_C_CONFIG # _LT_LANG_CXX_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a C++ compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to `libtool'. m4_defun([_LT_LANG_CXX_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl if test -n "$CXX" && ( test "X$CXX" != "Xno" && ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || (test "X$CXX" != "Xg++"))) ; then AC_PROG_CXXCPP else _lt_caught_CXX_error=yes fi AC_LANG_PUSH(C++) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_caught_CXX_error" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} CFLAGS=$CXXFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test "$GXX" = yes; then _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' else _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= fi if test "$GXX" = yes; then # Set up default GNU C++ configuration LT_PATH_LD # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test "$with_gnu_ld" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='${wl}' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) _LT_TAGVAR(ld_shlibs, $1)=yes case $host_os in aix3*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aix[[4-9]]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' if test "$GXX" = yes; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. _LT_TAGVAR(always_export_symbols, $1)=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an empty # executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared # libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in ,cl* | no,cl*) # Native MSVC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ func_to_tool_file "$lt_outputfile"~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; freebsd2.*) # C++ shared libraries reported to be fairly broken before # switch to ELF _LT_TAGVAR(ld_shlibs, $1)=no ;; freebsd-elf*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; freebsd* | dragonfly*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions _LT_TAGVAR(ld_shlibs, $1)=yes ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; hpux9*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; hpux10*|hpux11*) if test $with_gnu_ld = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) ;; *) _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes; then if test $with_gnu_ld = no; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test "$GXX" = yes; then if test "$with_gnu_ld" = no; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' fi fi _LT_TAGVAR(link_all_deplibs, $1)=yes ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ $RANLIB $oldlib' _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ;; cxx*) # Compaq C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; m88k*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) _LT_TAGVAR(ld_shlibs, $1)=yes ;; openbsd2*) # C++ shared libraries are fairly broken _LT_TAGVAR(ld_shlibs, $1)=no ;; openbsd*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; cxx*) case $host in osf3*) _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' ;; *) _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ $RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ;; esac _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' case $host in osf3*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # g++ 2.7 appears to require `-G' NOT `-shared' on this # platform. _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ '"$_LT_TAGVAR(old_archive_cmds, $1)" _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ '"$_LT_TAGVAR(reload_cmds, $1)" ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no _LT_TAGVAR(GCC, $1)="$GXX" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test "$_lt_caught_CXX_error" != yes AC_LANG_POP ])# _LT_LANG_CXX_CONFIG # _LT_FUNC_STRIPNAME_CNF # ---------------------- # func_stripname_cnf prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # # This function is identical to the (non-XSI) version of func_stripname, # except this one can be used by m4 code that may be executed by configure, # rather than the libtool script. m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl AC_REQUIRE([_LT_DECL_SED]) AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) func_stripname_cnf () { case ${2} in .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; esac } # func_stripname_cnf ])# _LT_FUNC_STRIPNAME_CNF # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) # --------------------------------- # Figure out "hidden" library dependencies from verbose # compiler output when linking a shared library. # Parse the compiler output and extract the necessary # objects, libraries and library flags. m4_defun([_LT_SYS_HIDDEN_LIBDEPS], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl # Dependencies to place before and after the object being linked: _LT_TAGVAR(predep_objects, $1)= _LT_TAGVAR(postdep_objects, $1)= _LT_TAGVAR(predeps, $1)= _LT_TAGVAR(postdeps, $1)= _LT_TAGVAR(compiler_lib_search_path, $1)= dnl we can't use the lt_simple_compile_test_code here, dnl because it contains code intended for an executable, dnl not a library. It's possible we should let each dnl tag define a new lt_????_link_test_code variable, dnl but it's only used here... m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF int a; void foo (void) { a = 0; } _LT_EOF ], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF ], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer*4 a a=0 return end _LT_EOF ], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer a a=0 return end _LT_EOF ], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF public class foo { private int a; public void bar (void) { a = 0; } }; _LT_EOF ], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF package foo func foo() { } _LT_EOF ]) _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; *\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; esac dnl Parse the compiler output and extract the necessary dnl objects, libraries and library flags. if AC_TRY_EVAL(ac_compile); then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case ${prev}${p} in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test $p = "-L" || test $p = "-R"; then prev=$p continue fi # Expand the sysroot to ease extracting the directories later. if test -z "$prev"; then case $p in -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; esac fi case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac if test "$pre_test_object_deps_done" = no; then case ${prev} in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" else _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$_LT_TAGVAR(postdeps, $1)"; then _LT_TAGVAR(postdeps, $1)="${prev}${p}" else _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" fi fi prev= ;; *.lto.$objext) ;; # Ignore GCC LTO objects *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test "$pre_test_object_deps_done" = no; then if test -z "$_LT_TAGVAR(predep_objects, $1)"; then _LT_TAGVAR(predep_objects, $1)="$p" else _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" fi else if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then _LT_TAGVAR(postdep_objects, $1)="$p" else _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling $1 test program" fi $RM -f confest.$objext CFLAGS=$_lt_libdeps_save_CFLAGS # PORTME: override above test on systems where it is broken m4_if([$1], [CXX], [case $host_os in interix[[3-9]]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. _LT_TAGVAR(predep_objects,$1)= _LT_TAGVAR(postdep_objects,$1)= _LT_TAGVAR(postdeps,$1)= ;; linux*) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac if test "$solaris_use_stlport4" != yes; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac # Adding this requires a known-good setup of shared libraries for # Sun compiler versions before 5.6, else PIC objects from an old # archive will be linked into the output, leading to subtle bugs. if test "$solaris_use_stlport4" != yes; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; esac ;; esac ]) case " $_LT_TAGVAR(postdeps, $1) " in *" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; esac _LT_TAGVAR(compiler_lib_search_dirs, $1)= if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` fi _LT_TAGDECL([], [compiler_lib_search_dirs], [1], [The directories searched by this compiler when creating a shared library]) _LT_TAGDECL([], [predep_objects], [1], [Dependencies to place before and after the objects being linked to create a shared library]) _LT_TAGDECL([], [postdep_objects], [1]) _LT_TAGDECL([], [predeps], [1]) _LT_TAGDECL([], [postdeps], [1]) _LT_TAGDECL([], [compiler_lib_search_path], [1], [The library search path used internally by the compiler when linking a shared library]) ])# _LT_SYS_HIDDEN_LIBDEPS # _LT_LANG_F77_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a Fortran 77 compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_F77_CONFIG], [AC_LANG_PUSH(Fortran 77) if test -z "$F77" || test "X$F77" = "Xno"; then _lt_disable_F77=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for f77 test sources. ac_ext=f # Object file extension for compiled f77 test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the F77 compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_disable_F77" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${F77-"f77"} CFLAGS=$FFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) GCC=$G77 if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)="$G77" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC="$lt_save_CC" CFLAGS="$lt_save_CFLAGS" fi # test "$_lt_disable_F77" != yes AC_LANG_POP ])# _LT_LANG_F77_CONFIG # _LT_LANG_FC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for a Fortran compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_FC_CONFIG], [AC_LANG_PUSH(Fortran) if test -z "$FC" || test "X$FC" = "Xno"; then _lt_disable_FC=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for fc test sources. ac_ext=${ac_fc_srcext-f} # Object file extension for compiled fc test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the FC compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_disable_FC" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${FC-"f95"} CFLAGS=$FCFLAGS compiler=$CC GCC=$ac_cv_fc_compiler_gnu _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS fi # test "$_lt_disable_FC" != yes AC_LANG_POP ])# _LT_LANG_FC_CONFIG # _LT_LANG_GCJ_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Java Compiler compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_GCJ_CONFIG], [AC_REQUIRE([LT_PROG_GCJ])dnl AC_LANG_SAVE # Source file extension for Java test sources. ac_ext=java # Object file extension for compiled Java test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="class foo {}" # Code to be used in simple link tests lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GCJ-"gcj"} CFLAGS=$GCJFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)="$LD" _LT_CC_BASENAME([$compiler]) # GCJ did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GCJ_CONFIG # _LT_LANG_GO_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Go compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_GO_CONFIG], [AC_REQUIRE([LT_PROG_GO])dnl AC_LANG_SAVE # Source file extension for Go test sources. ac_ext=go # Object file extension for compiled Go test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="package main; func main() { }" # Code to be used in simple link tests lt_simple_link_test_code='package main; func main() { }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GOC-"gccgo"} CFLAGS=$GOFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)="$LD" _LT_CC_BASENAME([$compiler]) # Go did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GO_CONFIG # _LT_LANG_RC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for the Windows resource compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_RC_CONFIG], [AC_REQUIRE([LT_PROG_RC])dnl AC_LANG_SAVE # Source file extension for RC test sources. ac_ext=rc # Object file extension for compiled RC test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' # Code to be used in simple link tests lt_simple_link_test_code="$lt_simple_compile_test_code" # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC= CC=${RC-"windres"} CFLAGS= compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes if test -n "$compiler"; then : _LT_CONFIG($1) fi GCC=$lt_save_GCC AC_LANG_RESTORE CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_RC_CONFIG # LT_PROG_GCJ # ----------- AC_DEFUN([LT_PROG_GCJ], [m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], [AC_CHECK_TOOL(GCJ, gcj,) test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" AC_SUBST(GCJFLAGS)])])[]dnl ]) # Old name: AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_GCJ], []) # LT_PROG_GO # ---------- AC_DEFUN([LT_PROG_GO], [AC_CHECK_TOOL(GOC, gccgo,) ]) # LT_PROG_RC # ---------- AC_DEFUN([LT_PROG_RC], [AC_CHECK_TOOL(RC, windres,) ]) # Old name: AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_RC], []) # _LT_DECL_EGREP # -------------- # If we don't have a new enough Autoconf to choose the best grep # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_EGREP], [AC_REQUIRE([AC_PROG_EGREP])dnl AC_REQUIRE([AC_PROG_FGREP])dnl test -z "$GREP" && GREP=grep _LT_DECL([], [GREP], [1], [A grep program that handles long lines]) _LT_DECL([], [EGREP], [1], [An ERE matcher]) _LT_DECL([], [FGREP], [1], [A literal string matcher]) dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too AC_SUBST([GREP]) ]) # _LT_DECL_OBJDUMP # -------------- # If we don't have a new enough Autoconf to choose the best objdump # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_OBJDUMP], [AC_CHECK_TOOL(OBJDUMP, objdump, false) test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) AC_SUBST([OBJDUMP]) ]) # _LT_DECL_DLLTOOL # ---------------- # Ensure DLLTOOL variable is set. m4_defun([_LT_DECL_DLLTOOL], [AC_CHECK_TOOL(DLLTOOL, dlltool, false) test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program]) AC_SUBST([DLLTOOL]) ]) # _LT_DECL_SED # ------------ # Check for a fully-functional sed program, that truncates # as few characters as possible. Prefer GNU sed if found. m4_defun([_LT_DECL_SED], [AC_PROG_SED test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" _LT_DECL([], [SED], [1], [A sed program that does not truncate output]) _LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], [Sed that helps us avoid accidentally triggering echo(1) options like -n]) ])# _LT_DECL_SED m4_ifndef([AC_PROG_SED], [ ############################################################ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_SED. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # ############################################################ m4_defun([AC_PROG_SED], [AC_MSG_CHECKING([for a sed that does not truncate output]) AC_CACHE_VAL(lt_cv_path_SED, [# Loop through the user's path and test for sed and gsed. # Then use that list of sed's as ones to test for truncation. as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for lt_ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" fi done done done IFS=$as_save_IFS lt_ac_max=0 lt_ac_count=0 # Add /usr/xpg4/bin/sed as it is typically found on Solaris # along with /bin/sed that truncates output. for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do test ! -f $lt_ac_sed && continue cat /dev/null > conftest.in lt_ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >conftest.in # Check for GNU sed and select it if it is found. if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then lt_cv_path_SED=$lt_ac_sed break fi while true; do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo >>conftest.nl $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break cmp -s conftest.out conftest.nl || break # 10000 chars as input seems more than enough test $lt_ac_count -gt 10 && break lt_ac_count=`expr $lt_ac_count + 1` if test $lt_ac_count -gt $lt_ac_max; then lt_ac_max=$lt_ac_count lt_cv_path_SED=$lt_ac_sed fi done done ]) SED=$lt_cv_path_SED AC_SUBST([SED]) AC_MSG_RESULT([$SED]) ])#AC_PROG_SED ])#m4_ifndef # Old name: AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_SED], []) # _LT_CHECK_SHELL_FEATURES # ------------------------ # Find out whether the shell is Bourne or XSI compatible, # or has some other useful features. m4_defun([_LT_CHECK_SHELL_FEATURES], [AC_MSG_CHECKING([whether the shell understands some XSI constructs]) # Try some XSI features xsi_shell=no ( _lt_dummy="a/b/c" test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ = c,a/b,b/c, \ && eval 'test $(( 1 + 1 )) -eq 2 \ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ && xsi_shell=yes AC_MSG_RESULT([$xsi_shell]) _LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) AC_MSG_CHECKING([whether the shell understands "+="]) lt_shell_append=no ( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ >/dev/null 2>&1 \ && lt_shell_append=yes AC_MSG_RESULT([$lt_shell_append]) _LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi _LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac _LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl ])# _LT_CHECK_SHELL_FEATURES # _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY) # ------------------------------------------------------ # In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and # '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY. m4_defun([_LT_PROG_FUNCTION_REPLACE], [dnl { sed -e '/^$1 ()$/,/^} # $1 /c\ $1 ()\ {\ m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1]) } # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: ]) # _LT_PROG_REPLACE_SHELLFNS # ------------------------- # Replace existing portable implementations of several shell functions with # equivalent extended shell implementations where those features are available.. m4_defun([_LT_PROG_REPLACE_SHELLFNS], [if test x"$xsi_shell" = xyes; then _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac]) _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl func_basename_result="${1##*/}"]) _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac func_basename_result="${1##*/}"]) _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are # positional parameters, so assign one to ordinary parameter first. func_stripname_result=${3} func_stripname_result=${func_stripname_result#"${1}"} func_stripname_result=${func_stripname_result%"${2}"}]) _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl func_split_long_opt_name=${1%%=*} func_split_long_opt_arg=${1#*=}]) _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl func_split_short_opt_arg=${1#??} func_split_short_opt_name=${1%"$func_split_short_opt_arg"}]) _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl case ${1} in *.lo) func_lo2o_result=${1%.lo}.${objext} ;; *) func_lo2o_result=${1} ;; esac]) _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo]) _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))]) _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}]) fi if test x"$lt_shell_append" = xyes; then _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"]) _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl func_quote_for_eval "${2}" dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \ eval "${1}+=\\\\ \\$func_quote_for_eval_result"]) # Save a `func_append' function call where possible by direct use of '+=' sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: else # Save a `func_append' function call even when '+=' is not available sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: fi if test x"$_lt_function_replace_fail" = x":"; then AC_MSG_WARN([Unable to substitute extended shell functions in $ofile]) fi ]) # _LT_PATH_CONVERSION_FUNCTIONS # ----------------------------- # Determine which file name conversion functions should be used by # func_to_host_file (and, implicitly, by func_to_host_path). These are needed # for certain cross-compile configurations and native mingw. m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_MSG_CHECKING([how to convert $build file names to $host format]) AC_CACHE_VAL(lt_cv_to_host_file_cmd, [case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac ]) to_host_file_cmd=$lt_cv_to_host_file_cmd AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) _LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], [0], [convert $build file names to $host format])dnl AC_MSG_CHECKING([how to convert $build file names to toolchain format]) AC_CACHE_VAL(lt_cv_to_tool_file_cmd, [#assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac ]) to_tool_file_cmd=$lt_cv_to_tool_file_cmd AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) _LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], [0], [convert $build files to toolchain format])dnl ])# _LT_PATH_CONVERSION_FUNCTIONS mongodb-1.1.5/src/libmongoc/build/autotools/m4/ltoptions.m40000644000175000017500000003007312673034026023514 0ustar jmikolajmikola# Helper functions for option handling. -*- Autoconf -*- # # Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, # Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 7 ltoptions.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) # _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) # ------------------------------------------ m4_define([_LT_MANGLE_OPTION], [[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) # _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) # --------------------------------------- # Set option OPTION-NAME for macro MACRO-NAME, and if there is a # matching handler defined, dispatch to it. Other OPTION-NAMEs are # saved as a flag. m4_define([_LT_SET_OPTION], [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), _LT_MANGLE_DEFUN([$1], [$2]), [m4_warning([Unknown $1 option `$2'])])[]dnl ]) # _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) # ------------------------------------------------------------ # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. m4_define([_LT_IF_OPTION], [m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) # _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) # ------------------------------------------------------- # Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME # are set. m4_define([_LT_UNLESS_OPTIONS], [m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), [m4_define([$0_found])])])[]dnl m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 ])[]dnl ]) # _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) # ---------------------------------------- # OPTION-LIST is a space-separated list of Libtool options associated # with MACRO-NAME. If any OPTION has a matching handler declared with # LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about # the unknown option and exit. m4_defun([_LT_SET_OPTIONS], [# Set options m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [_LT_SET_OPTION([$1], _LT_Option)]) m4_if([$1],[LT_INIT],[ dnl dnl Simply set some default values (i.e off) if boolean options were not dnl specified: _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no ]) _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no ]) dnl dnl If no reference was made to various pairs of opposing options, then dnl we run the default mode handler for the pair. For example, if neither dnl `shared' nor `disable-shared' was passed, we enable building of shared dnl archives by default: _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], [_LT_ENABLE_FAST_INSTALL]) ]) ])# _LT_SET_OPTIONS ## --------------------------------- ## ## Macros to handle LT_INIT options. ## ## --------------------------------- ## # _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) # ----------------------------------------- m4_define([_LT_MANGLE_DEFUN], [[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) # LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) # ----------------------------------------------- m4_define([LT_OPTION_DEFINE], [m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl ])# LT_OPTION_DEFINE # dlopen # ------ LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes ]) AU_DEFUN([AC_LIBTOOL_DLOPEN], [_LT_SET_OPTION([LT_INIT], [dlopen]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `dlopen' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) # win32-dll # --------- # Declare package support for building win32 dll's. LT_OPTION_DEFINE([LT_INIT], [win32-dll], [enable_win32_dll=yes case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) AC_CHECK_TOOL(AS, as, false) AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(OBJDUMP, objdump, false) ;; esac test -z "$AS" && AS=as _LT_DECL([], [AS], [1], [Assembler program])dnl test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl ])# win32-dll AU_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_REQUIRE([AC_CANONICAL_HOST])dnl _LT_SET_OPTION([LT_INIT], [win32-dll]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `win32-dll' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) # _LT_ENABLE_SHARED([DEFAULT]) # ---------------------------- # implement the --enable-shared flag, and supports the `shared' and # `disable-shared' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_SHARED], [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([shared], [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) _LT_DECL([build_libtool_libs], [enable_shared], [0], [Whether or not to build shared libraries]) ])# _LT_ENABLE_SHARED LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) # Old names: AC_DEFUN([AC_ENABLE_SHARED], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) ]) AC_DEFUN([AC_DISABLE_SHARED], [_LT_SET_OPTION([LT_INIT], [disable-shared]) ]) AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_SHARED], []) dnl AC_DEFUN([AM_DISABLE_SHARED], []) # _LT_ENABLE_STATIC([DEFAULT]) # ---------------------------- # implement the --enable-static flag, and support the `static' and # `disable-static' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_STATIC], [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([static], [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_static=]_LT_ENABLE_STATIC_DEFAULT) _LT_DECL([build_old_libs], [enable_static], [0], [Whether or not to build static libraries]) ])# _LT_ENABLE_STATIC LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) # Old names: AC_DEFUN([AC_ENABLE_STATIC], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) ]) AC_DEFUN([AC_DISABLE_STATIC], [_LT_SET_OPTION([LT_INIT], [disable-static]) ]) AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_STATIC], []) dnl AC_DEFUN([AM_DISABLE_STATIC], []) # _LT_ENABLE_FAST_INSTALL([DEFAULT]) # ---------------------------------- # implement the --enable-fast-install flag, and support the `fast-install' # and `disable-fast-install' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_FAST_INSTALL], [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([fast-install], [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) _LT_DECL([fast_install], [enable_fast_install], [0], [Whether or not to optimize for fast installation])dnl ])# _LT_ENABLE_FAST_INSTALL LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) # Old names: AU_DEFUN([AC_ENABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `fast-install' option into LT_INIT's first parameter.]) ]) AU_DEFUN([AC_DISABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], [disable-fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `disable-fast-install' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) # _LT_WITH_PIC([MODE]) # -------------------- # implement the --with-pic flag, and support the `pic-only' and `no-pic' # LT_INIT options. # MODE is either `yes' or `no'. If omitted, it defaults to `both'. m4_define([_LT_WITH_PIC], [AC_ARG_WITH([pic], [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], [lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for lt_pkg in $withval; do IFS="$lt_save_ifs" if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS="$lt_save_ifs" ;; esac], [pic_mode=default]) test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl ])# _LT_WITH_PIC LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) # Old name: AU_DEFUN([AC_LIBTOOL_PICMODE], [_LT_SET_OPTION([LT_INIT], [pic-only]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `pic-only' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) ## ----------------- ## ## LTDL_INIT Options ## ## ----------------- ## m4_define([_LTDL_MODE], []) LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], [m4_define([_LTDL_MODE], [nonrecursive])]) LT_OPTION_DEFINE([LTDL_INIT], [recursive], [m4_define([_LTDL_MODE], [recursive])]) LT_OPTION_DEFINE([LTDL_INIT], [subproject], [m4_define([_LTDL_MODE], [subproject])]) m4_define([_LTDL_TYPE], []) LT_OPTION_DEFINE([LTDL_INIT], [installable], [m4_define([_LTDL_TYPE], [installable])]) LT_OPTION_DEFINE([LTDL_INIT], [convenience], [m4_define([_LTDL_TYPE], [convenience])]) mongodb-1.1.5/src/libmongoc/build/autotools/m4/ltsugar.m40000644000175000017500000001042412673034026023140 0ustar jmikolajmikola# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # # Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 6 ltsugar.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) # lt_join(SEP, ARG1, [ARG2...]) # ----------------------------- # Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their # associated separator. # Needed until we can rely on m4_join from Autoconf 2.62, since all earlier # versions in m4sugar had bugs. m4_define([lt_join], [m4_if([$#], [1], [], [$#], [2], [[$2]], [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) m4_define([_lt_join], [m4_if([$#$2], [2], [], [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) # lt_car(LIST) # lt_cdr(LIST) # ------------ # Manipulate m4 lists. # These macros are necessary as long as will still need to support # Autoconf-2.59 which quotes differently. m4_define([lt_car], [[$1]]) m4_define([lt_cdr], [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], [$#], 1, [], [m4_dquote(m4_shift($@))])]) m4_define([lt_unquote], $1) # lt_append(MACRO-NAME, STRING, [SEPARATOR]) # ------------------------------------------ # Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. # Note that neither SEPARATOR nor STRING are expanded; they are appended # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). # No SEPARATOR is output if MACRO-NAME was previously undefined (different # than defined and empty). # # This macro is needed until we can rely on Autoconf 2.62, since earlier # versions of m4sugar mistakenly expanded SEPARATOR but not STRING. m4_define([lt_append], [m4_define([$1], m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) # lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) # ---------------------------------------------------------- # Produce a SEP delimited list of all paired combinations of elements of # PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list # has the form PREFIXmINFIXSUFFIXn. # Needed until we can rely on m4_combine added in Autoconf 2.62. m4_define([lt_combine], [m4_if(m4_eval([$# > 3]), [1], [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl [[m4_foreach([_Lt_prefix], [$2], [m4_foreach([_Lt_suffix], ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) # lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) # ----------------------------------------------------------------------- # Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited # by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. m4_define([lt_if_append_uniq], [m4_ifdef([$1], [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], [lt_append([$1], [$2], [$3])$4], [$5])], [lt_append([$1], [$2], [$3])$4])]) # lt_dict_add(DICT, KEY, VALUE) # ----------------------------- m4_define([lt_dict_add], [m4_define([$1($2)], [$3])]) # lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) # -------------------------------------------- m4_define([lt_dict_add_subkey], [m4_define([$1($2:$3)], [$4])]) # lt_dict_fetch(DICT, KEY, [SUBKEY]) # ---------------------------------- m4_define([lt_dict_fetch], [m4_ifval([$3], m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) # lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) # ----------------------------------------------------------------- m4_define([lt_if_dict_fetch], [m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], [$5], [$6])]) # lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) # -------------------------------------------------------------- m4_define([lt_dict_filter], [m4_if([$5], [], [], [lt_join(m4_quote(m4_default([$4], [[, ]])), lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl ]) mongodb-1.1.5/src/libmongoc/build/autotools/m4/ltversion.m40000644000175000017500000000126212673034026023504 0ustar jmikolajmikola# ltversion.m4 -- version numbers -*- Autoconf -*- # # Copyright (C) 2004 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # @configure_input@ # serial 3337 ltversion.m4 # This file is part of GNU Libtool m4_define([LT_PACKAGE_VERSION], [2.4.2]) m4_define([LT_PACKAGE_REVISION], [1.3337]) AC_DEFUN([LTVERSION_VERSION], [macro_version='2.4.2' macro_revision='1.3337' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) mongodb-1.1.5/src/libmongoc/build/autotools/m4/lt~obsolete.m40000644000175000017500000001375612673034026024044 0ustar jmikolajmikola# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- # # Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004. # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 5 lt~obsolete.m4 # These exist entirely to fool aclocal when bootstrapping libtool. # # In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) # which have later been changed to m4_define as they aren't part of the # exported API, or moved to Autoconf or Automake where they belong. # # The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN # in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us # using a macro with the same name in our local m4/libtool.m4 it'll # pull the old libtool.m4 in (it doesn't see our shiny new m4_define # and doesn't know about Autoconf macros at all.) # # So we provide this file, which has a silly filename so it's always # included after everything else. This provides aclocal with the # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything # because those macros already exist, or will be overwritten later. # We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. # # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. # Yes, that means every name once taken will need to remain here until # we give up compatibility with versions before 1.7, at which point # we need to keep only those names which we still refer to. # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) mongodb-1.1.5/src/libmongoc/build/autotools/m4/pkg.m40000664000175000017500000001623112673034026022244 0ustar jmikolajmikola# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- # serial 1 (pkg-config-0.24) # # Copyright © 2004 Scott James Remnant . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # PKG_PROG_PKG_CONFIG([MIN-VERSION]) # ---------------------------------- AC_DEFUN([PKG_PROG_PKG_CONFIG], [m4_pattern_forbid([^_?PKG_[A-Z_]+$]) m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$]) AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility]) AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path]) AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path]) if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) fi if test -n "$PKG_CONFIG"; then _pkg_min_version=m4_default([$1], [0.9.0]) AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) PKG_CONFIG="" fi fi[]dnl ])# PKG_PROG_PKG_CONFIG # PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) # # Check to see whether a particular set of modules exists. Similar # to PKG_CHECK_MODULES(), but does not set variables or print errors. # # Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) # only at the first occurence in configure.ac, so if the first place # it's called might be skipped (such as if it is within an "if", you # have to call PKG_CHECK_EXISTS manually # -------------------------------------------------------------- AC_DEFUN([PKG_CHECK_EXISTS], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl if test -n "$PKG_CONFIG" && \ AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then m4_default([$2], [:]) m4_ifvaln([$3], [else $3])dnl fi]) # _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) # --------------------------------------------- m4_define([_PKG_CONFIG], [if test -n "$$1"; then pkg_cv_[]$1="$$1" elif test -n "$PKG_CONFIG"; then PKG_CHECK_EXISTS([$3], [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes ], [pkg_failed=yes]) else pkg_failed=untried fi[]dnl ])# _PKG_CONFIG # _PKG_SHORT_ERRORS_SUPPORTED # ----------------------------- AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], [AC_REQUIRE([PKG_PROG_PKG_CONFIG]) if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi[]dnl ])# _PKG_SHORT_ERRORS_SUPPORTED # PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], # [ACTION-IF-NOT-FOUND]) # # # Note that if there is a possibility the first call to # PKG_CHECK_MODULES might not happen, you should be sure to include an # explicit call to PKG_PROG_PKG_CONFIG in your configure.ac # # # -------------------------------------------------------------- AC_DEFUN([PKG_CHECK_MODULES], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl pkg_failed=no AC_MSG_CHECKING([for $1]) _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) _PKG_CONFIG([$1][_LIBS], [libs], [$2]) m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS and $1[]_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details.]) if test $pkg_failed = yes; then AC_MSG_RESULT([no]) _PKG_SHORT_ERRORS_SUPPORTED if test $_pkg_short_errors_supported = yes; then $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` else $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD m4_default([$4], [AC_MSG_ERROR( [Package requirements ($2) were not met: $$1_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. _PKG_TEXT])[]dnl ]) elif test $pkg_failed = untried; then AC_MSG_RESULT([no]) m4_default([$4], [AC_MSG_FAILURE( [The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. _PKG_TEXT To get pkg-config, see .])[]dnl ]) else $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS $1[]_LIBS=$pkg_cv_[]$1[]_LIBS AC_MSG_RESULT([yes]) $3 fi[]dnl ])# PKG_CHECK_MODULES # PKG_INSTALLDIR(DIRECTORY) # ------------------------- # Substitutes the variable pkgconfigdir as the location where a module # should install pkg-config .pc files. By default the directory is # $libdir/pkgconfig, but the default can be changed by passing # DIRECTORY. The user can override through the --with-pkgconfigdir # parameter. AC_DEFUN([PKG_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])]) m4_pushdef([pkg_description], [pkg-config installation directory @<:@]pkg_default[@:>@]) AC_ARG_WITH([pkgconfigdir], [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],, [with_pkgconfigdir=]pkg_default) AC_SUBST([pkgconfigdir], [$with_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) ]) dnl PKG_INSTALLDIR # PKG_NOARCH_INSTALLDIR(DIRECTORY) # ------------------------- # Substitutes the variable noarch_pkgconfigdir as the location where a # module should install arch-independent pkg-config .pc files. By # default the directory is $datadir/pkgconfig, but the default can be # changed by passing DIRECTORY. The user can override through the # --with-noarch-pkgconfigdir parameter. AC_DEFUN([PKG_NOARCH_INSTALLDIR], [m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])]) m4_pushdef([pkg_description], [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@]) AC_ARG_WITH([noarch-pkgconfigdir], [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],, [with_noarch_pkgconfigdir=]pkg_default) AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir]) m4_popdef([pkg_default]) m4_popdef([pkg_description]) ]) dnl PKG_NOARCH_INSTALLDIR mongodb-1.1.5/src/libmongoc/build/autotools/m4/silent.m40000664000175000017500000000267212673034026022765 0ustar jmikolajmikoladnl Use GNU make's -s when available dnl dnl Copyright (c) 2010, Damien Lespiau dnl dnl DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE dnl TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION dnl dnl 0. You just DO WHAT THE FUCK YOU WANT TO. dnl dnl The above copyright notice and this permission notice shall be dnl included in all copies or substantial portions of the Software. dnl dnl Simply put this file in your m4 macro directory (as everyone should be dnl using AC_CONFIG_MACRO_DIR by now!) and add AS_AM_REALLY_SILENT somewhere dnl in your configure.ac AC_DEFUN([AS_AM_REALLY_SILENT], [ AC_MSG_CHECKING([whether ${MAKE-make} can be made more silent]) dnl And we even cache that FFS! AC_CACHE_VAL( [as_cv_prog_make_can_be_really_silent], [cat >confstfu.make <<\_WTF SHELL = /bin/sh all: @echo '@@@%%%clutter rocks@@@%%%' _WTF as_cv_prog_make_can_be_really_silent=no case `${MAKE-make} -f confstfu.make -s --no-print-directory 2>/dev/null` in *'@@@%%%clutter rocks@@@%%%'*) test $? = 0 && as_cv_prog_make_can_be_really_silent=yes esac rm -f confstfu.make]) if test $as_cv_prog_make_can_be_really_silent = yes; then AC_MSG_RESULT([yes]) make_flags='`\ if test "x$(AM_DEFAULT_VERBOSITY)" = x0; then \ test -z "$V" -o "x$V" = x0 && echo -s; \ else \ test "x$V" = x0 && echo -s; \ fi`' AC_SUBST([AM_MAKEFLAGS], [$make_flags]) else AC_MSG_RESULT([no]) fi ]) mongodb-1.1.5/src/libmongoc/build/autotools/AutoHarden.m40000664000175000017500000000476412673034026023205 0ustar jmikolajmikola# We want to check for compiler flag support, but there is no way to make # clang's "argument unused" warning fatal. So we invoke the compiler through a # wrapper script that greps for this message. saved_CC="$CC" saved_CXX="$CXX" saved_LD="$LD" flag_wrap="$srcdir/scripts/wrap-compiler-for-flag-check" CC="$flag_wrap $CC" CXX="$flag_wrap $CXX" LD="$flag_wrap $LD" # We use the same hardening flags for C and C++. We must check that each flag # is supported by both compilers. AC_DEFUN([check_cc_cxx_flag], [AC_LANG_PUSH(C) AX_CHECK_COMPILE_FLAG([$1], [AC_LANG_PUSH(C++) AX_CHECK_COMPILE_FLAG([$1], [$2], [$3], [-Werror $4]) AC_LANG_POP(C++)], [$3], [-Werror $4]) AC_LANG_POP(C)]) AC_DEFUN([check_link_flag], [AX_CHECK_LINK_FLAG([$1], [$2], [$3], [-Werror $4])]) AC_ARG_ENABLE([hardening], [AS_HELP_STRING([--enable-hardening], [Enable compiler and linker options to frustrate memory corruption exploits @<:@yes@:>@])], [enable_hardening="$enableval"], [enable_hardening="yes"]) HARDEN_CFLAGS="" HARDEN_LDFLAGS="" AS_IF([test x"$enable_hardening" != x"no"], [ check_cc_cxx_flag([-fno-strict-overflow], [HARDEN_CFLAGS="$HARDEN_CFLAGS -fno-strict-overflow"]) # This one will likely succeed, even on platforms where it does nothing. check_cc_cxx_flag([-D_FORTIFY_SOURCE=2], [HARDEN_CFLAGS="$HARDEN_CFLAGS -D_FORTIFY_SOURCE=2"]) check_cc_cxx_flag([-fstack-protector-all], [check_link_flag([-fstack-protector-all], [HARDEN_CFLAGS="$HARDEN_CFLAGS -fstack-protector-all" check_cc_cxx_flag([-Wstack-protector], [HARDEN_CFLAGS="$HARDEN_CFLAGS -Wstack-protector"], [], [-fstack-protector-all]) check_cc_cxx_flag([--param ssp-buffer-size=1], [HARDEN_CFLAGS="$HARDEN_CFLAGS --param ssp-buffer-size=1"], [], [-fstack-protector-all])])]) # At the link step, we might want -pie (GCC) or -Wl,-pie (Clang on OS X) # # The linker checks also compile code, so we need to include -fPIE as well. check_cc_cxx_flag([-fPIE], [check_link_flag([-fPIE -pie], [HARDEN_CFLAGS="$HARDEN_CFLAGS -fPIE" HARDEN_LDFLAGS="$HARDEN_LDFLAGS -pie"], [check_link_flag([-fPIE -Wl,-pie], [HARDEN_CFLAGS="$HARDEN_CFLAGS -fPIE" HARDEN_LDFLAGS="$HARDEN_LDFLAGS -Wl,-pie"])])]) check_link_flag([-Wl,-z,relro], [HARDEN_LDFLAGS="$HARDEN_LDFLAGS -Wl,-z,relro" check_link_flag([-Wl,-z,now], [HARDEN_LDFLAGS="$HARDEN_LDFLAGS -Wl,-z,now"])])]) AC_SUBST([HARDEN_CFLAGS]) AC_SUBST([HARDEN_LDFLAGS]) # End of flag tests. CC="$saved_CC" CXX="$saved_CXX" LD="$saved_LD" mongodb-1.1.5/src/libmongoc/build/autotools/CheckCompiler.m40000664000175000017500000000341612673034026023654 0ustar jmikolajmikola# If CFLAGS and CXXFLAGS are unset, default to empty. # This is to tell automake not to include '-g' if C{XX,}FLAGS is not set. # For more info - http://www.gnu.org/software/automake/manual/autoconf.html#C_002b_002b-Compiler if test -z "$CXXFLAGS"; then CXXFLAGS="" fi if test -z "$CFLAGS"; then CFLAGS="" fi AC_PROG_CC AC_PROG_CXX # Check that an appropriate C compiler is available. c_compiler="unknown" AC_LANG_PUSH([C]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([ #if !(defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER)) #error Not a supported GCC compiler #endif #if defined(__GNUC__) #define GCC_VERSION (__GNUC__ * 10000 \ + __GNUC_MINOR__ * 100 \ + __GNUC_PATCHLEVEL__) #if GCC_VERSION < 40100 #error Not a supported GCC compiler #endif #endif ])], [c_compiler="gcc"], []) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([ #if defined(__clang__) #define CLANG_VERSION (__clang_major__ * 10000 \ + __clang_minor__ * 100 \ + __clang_patchlevel__) #if CLANG_VERSION < 30300 #error Not a supported Clang compiler #endif #endif ])], [c_compiler="clang"], []) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([ #if !(defined(__SUNPRO_C)) #error Not a supported Sun compiler #endif ])], [c_compiler="sun"], []) AC_LANG_POP([C]) if test "$c_compiler" = "unknown"; then AC_MSG_ERROR([Compiler GCC >= 4.1 or Clang >= 3.3 is required for C compilation]) fi # GLibc 2.19 complains about both _BSD_SOURCE and _GNU_SOURCE. The _GNU_SOURCE # contains everything anyway. So just use that. AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #ifndef __GLIBC__ #error not glibc #endif ]], [])], LIBC_FEATURES="-D_GNU_SOURCE", LIBC_FEATURES="-D_BSD_SOURCE") AC_SUBST(LIBC_FEATURES) AC_C_CONST AC_C_INLINE AC_C_TYPEOF mongodb-1.1.5/src/libmongoc/build/autotools/CheckHost.m40000664000175000017500000000135512673034026023017 0ustar jmikolajmikolaAC_CANONICAL_HOST os_win32=no os_linux=no os_freebsd=no os_gnu=no case "$host" in *-mingw*|*-*-cygwin*) os_win32=yes TARGET_OS=windows ;; *-*-*netbsd*) os_netbsd=yes TARGET_OS=unix ;; *-*-*freebsd*) os_freebsd=yes TARGET_OS=unix ;; *-*-*openbsd*) os_openbsd=yes TARGET_OS=unix ;; *-*-linux*) os_linux=yes os_gnu=yes TARGET_OS=unix ;; *-*-solaris*) os_solaris=yes TARGET_OS=unix ;; *-*-darwin*) os_darwin=yes TARGET_OS=unix ;; gnu*|k*bsd*-gnu*) os_gnu=yes TARGET_OS=unix ;; *) AC_MSG_WARN([*** Please add $host to configure.ac checks!]) ;; esac mongodb-1.1.5/src/libmongoc/build/autotools/CheckProgs.m40000664000175000017500000000062312673034026023171 0ustar jmikolajmikolaAC_PATH_PROG(PERL, perl) if test -z "$PERL"; then AC_MSG_ERROR([You need 'perl' to compile libbson]) fi AC_PATH_PROG(MV, mv) if test -z "$MV"; then AC_MSG_ERROR([You need 'mv' to compile libbson]) fi AC_PATH_PROG(GREP, grep) if test -z "$GREP"; then AC_MSG_ERROR([You need 'grep' to compile libbson]) fi # Optional for documentation AC_PATH_PROG(YELP_BUILD, yelp-build) AC_PROG_INSTALL mongodb-1.1.5/src/libmongoc/build/autotools/CheckSSL.m40000664000175000017500000000326312673034026022543 0ustar jmikolajmikolaAC_ARG_ENABLE([ssl], [AS_HELP_STRING([--enable-ssl=@<:@auto/yes/no@:>@], [Use OpenSSL for TLS connections and SCRAM-SHA-1 authentication. NOTE: OpenSSL is required for authenticating to MongoDB 3.0 and later])], [], [enable_ssl=auto]) AS_IF([test "$enable_ssl" != "no"],[ PKG_CHECK_MODULES(SSL, [openssl], [enable_ssl=yes], [ AS_IF([test "$enable_ssl" != "no"],[ AC_CHECK_LIB([ssl],[SSL_library_init],[have_ssl_lib=yes],[have_ssl_lib=no]) AC_CHECK_LIB([crypto],[CRYPTO_set_locking_callback],[have_crypto_lib=yes],[have_crypto_lib=no]) if test "$enable_ssl" = "yes"; then if test "$have_ssl_lib" = "no" -o "$have_crypto_lib" = "no" ; then AC_MSG_ERROR([You must install the OpenSSL libraries and development headers to enable SSL support.]) fi fi AC_CHECK_HEADERS([openssl/bio.h openssl/ssl.h openssl/err.h openssl/crypto.h], [have_ssl_headers=yes], [have_ssl_headers=no]) if test "$have_ssl_headers" = "no" -a "$enable_ssl" = "yes" ; then AC_MSG_ERROR([You must install the OpenSSL development headers to enable SSL support.]) fi if test "$have_ssl_headers" = "yes" -a "$have_ssl_lib" = "yes" -a "$have_crypto_lib" = "yes"; then SSL_LIBS="-lssl -lcrypto" enable_ssl=yes else enable_ssl=no fi ]) ]) ]) AM_CONDITIONAL([ENABLE_SSL], [test "$enable_ssl" = "yes"]) AC_SUBST(SSL_CFLAGS) AC_SUBST(SSL_LIBS) dnl Let mongoc-config.h.in know about SSL status. if test "$enable_ssl" = "yes" ; then AC_SUBST(MONGOC_ENABLE_SSL, 1) else AC_SUBST(MONGOC_ENABLE_SSL, 0) fi mongodb-1.1.5/src/libmongoc/build/autotools/CheckSasl.m40000664000175000017500000000354512673034026023007 0ustar jmikolajmikolaAC_ARG_ENABLE([sasl], [AS_HELP_STRING([--enable-sasl=@<:@auto/yes/no@:>@], [Use libsasl for Kerberos.])], [], [enable_sasl=auto]) sasl_mode=no AS_IF([test "$enable_sasl" != "no"],[ PKG_CHECK_MODULES(SASL, [libsasl2], [sasl_mode=sasl2], [ AS_IF([test "$enable_sasl" != "no"],[ AC_CHECK_LIB([sasl2],[sasl_client_init],[have_sasl2_lib=yes],[have_sasl2_lib=no]) AC_CHECK_LIB([sasl],[sasl_client_init],[have_sasl_lib=yes],[have_sasl_lib=no]) if test "$have_sasl_lib" = "no" -a "$have_sasl2_lib" = "no" -a "$enable_sasl" = "yes" ; then AC_MSG_ERROR([You must install the Cyrus SASL libraries and development headers to enable SASL support.]) fi AC_CHECK_HEADER([sasl/sasl.h],[have_sasl_headers=yes],[have_sasl_headers=no]) if test "$have_sasl_headers" = "no" -a "$enable_sasl" = "yes" ; then AC_MSG_ERROR([You must install the Cyrus SASL development headers to enable SASL support.]) fi if test "$have_sasl_headers" -a "$have_sasl2_lib" = "yes" ; then sasl_mode=sasl2 SASL_LIBS=-lsasl2 fi if test "$have_sasl_headers" -a "$have_sasl_lib" = "yes" ; then sasl_mode=sasl SASL_LIBS=-lsasl fi ]) ]) ]) AM_CONDITIONAL([ENABLE_SASL], [test "$sasl_mode" != "no"]) AC_SUBST(SASL_CFLAGS) AC_SUBST(SASL_LIBS) dnl Let mongoc-config.h.in know about SASL status. if test "$sasl_mode" != "no" ; then AC_SUBST(MONGOC_ENABLE_SASL, 1) AC_CHECK_LIB([sasl2],[sasl_client_done], [have_sasl_client_done=yes], [have_sasl_client_done=no]) if test "$have_sasl_client_done" = "yes" ; then AC_SUBST(MONGOC_HAVE_SASL_CLIENT_DONE, 1) else AC_SUBST(MONGOC_HAVE_SASL_CLIENT_DONE, 0) fi else AC_SUBST(MONGOC_ENABLE_SASL, 0) AC_SUBST(MONGOC_HAVE_SASL_CLIENT_DONE, 0) fi mongodb-1.1.5/src/libmongoc/build/autotools/CheckTarget.m40000664000175000017500000000114712673034026023327 0ustar jmikolajmikolaAC_CANONICAL_SYSTEM enable_crosscompile=no if test "x$host" != "x$target"; then enable_crosscompile=yes case "$target" in *-mingw*|*-*-cygwin*) TARGET_OS=windows ;; arm*-darwin*) TARGET_OS=unix ;; powerpc64-*-linux-gnu) TARGET_OS=unix ;; arm*-linux-*) TARGET_OS=unix ;; *) AC_MSG_ERROR([Cross compiling is not supported for target $target]) ;; esac fi AC_SUBST(BSON_OS, 1) if test "$TARGET_OS" = "windows"; then AC_SUBST(BSON_OS, 2) fi mongodb-1.1.5/src/libmongoc/build/autotools/Coverage.m40000664000175000017500000000031412673034026022671 0ustar jmikolajmikolaCOVERAGE_CFLAGS="" COVERAGE_LDFLAGS="" if test "$enable_coverage" = "yes"; then COVERAGE_CFLAGS="--coverage -g" COVERAGE_LDFLAGS="-lgcov" fi AC_SUBST(COVERAGE_CFLAGS) AC_SUBST(COVERAGE_LDFLAGS) mongodb-1.1.5/src/libmongoc/build/autotools/FindDependencies.m40000664000175000017500000000223612673034026024332 0ustar jmikolajmikola # Solaris needs to link against socket libs. if test "$os_solaris" = "yes"; then CFLAGS="$CFLAGS -D__EXTENSIONS__" CFLAGS="$CFLAGS -D_XOPEN_SOURCE=1" CFLAGS="$CFLAGS -D_XOPEN_SOURCE_EXTENDED=1" LDFLAGS="$LDFLAGS -lsocket -lnsl" fi # Check if we should enable the bundled libbson. if test "$with_libbson" = "auto"; then PKG_CHECK_MODULES(BSON, libbson-1.0 >= libbson_required_version, [with_libbson=system], [with_libbson=bundled]) fi AM_CONDITIONAL(ENABLE_LIBBSON, [test "$with_libbson" = "bundled"]) # Check for shm functions. AC_CHECK_FUNCS([shm_open], [SHM_LIB=], [AC_CHECK_LIB([rt], [shm_open], [SHM_LIB=-lrt], [SHM_LIB=])]) AC_SUBST([SHM_LIB]) # Check for sched_getcpu AC_CHECK_FUNCS([sched_getcpu]) # Check for clock_gettime AC_SEARCH_LIBS([clock_gettime], [rt], [ AC_DEFINE(HAVE_CLOCK_GETTIME, 1, [Have clock_gettime]) ]) AS_IF([test "$ac_cv_search_clock_gettime" = "-lrt"], [LDFLAGS="$LDFLAGS -lrt"]) AS_IF([test "$enable_rdtscp" = "yes"], [CPPFLAGS="$CPPFLAGS -DENABLE_RDTSCP"]) AS_IF([test "$enable_shm_counters" = "yes"], [CPPFLAGS="$CPPFLAGS -DMONGOC_ENABLE_SHM_COUNTERS"]) AX_PTHREAD mongodb-1.1.5/src/libmongoc/build/autotools/LDVersionScript.m40000664000175000017500000000341412673034026024174 0ustar jmikolajmikola# ld-version-script.m4 serial 3 dnl Copyright (C) 2008-2013 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. dnl From Simon Josefsson # FIXME: The test below returns a false positive for mingw # cross-compiles, 'local:' statements does not reduce number of # exported symbols in a DLL. Use --disable-ld-version-script to work # around the problem. # gl_LD_VERSION_SCRIPT # -------------------- # Check if LD supports linker scripts, and define automake conditional # HAVE_LD_VERSION_SCRIPT if so. AC_DEFUN([gl_LD_VERSION_SCRIPT], [ AC_ARG_ENABLE([ld-version-script], AS_HELP_STRING([--enable-ld-version-script], [enable linker version script (default is enabled when possible)]), [have_ld_version_script=$enableval], []) if test -z "$have_ld_version_script"; then AC_MSG_CHECKING([if LD -Wl,--version-script works]) save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -Wl,--version-script=conftest.map" cat > conftest.map < conftest.map <= libbson_required_version], [with_libbson=system], [with_libbson=bundled])]) # If we are to use the system, check for libbson enforcing success. AS_IF([test "x${with_libbson}" = xsystem], [PKG_CHECK_MODULES(BSON, [libbson-1.0 >= libbson_required_version], [], [AC_MSG_ERROR([ -------------------------------------- The libbson-1.0 library could not be found on your system. Please install libbson-1.0 development package or set --with-libbson=auto. -------------------------------------- ])])]) # If we are using the bundled libbson, recurse into its configure. AS_IF([test "x${with_libbson}" = xbundled],[ AC_CONFIG_SUBDIRS([src/libbson]) AC_SUBST(BSON_CFLAGS, "-I${srcdir}/src/libbson/src/bson -Isrc/libbson/src/bson") AC_SUBST(BSON_LIBS, "src/libbson/libbson-1.0.la") ]) mongodb-1.1.5/src/libmongoc/build/autotools/MaintainerFlags.m40000664000175000017500000000363212673034026024210 0ustar jmikolajmikolaAS_IF([test "x$enable_maintainer_flags" = "xyes" && test "x$GCC" = "xyes"], [check_cc_cxx_flag([-Wall], [CFLAGS="$CFLAGS -Wall"]) check_cc_cxx_flag([-Waggregate-return], [CFLAGS="$CFLAGS -Waggregate-return"]) check_cc_cxx_flag([-Wcast-align], [CFLAGS="$CFLAGS -Wcast-align"]) check_cc_cxx_flag([-Wdeclaration-after-statement], [CFLAGS="$CFLAGS -Wdeclaration-after-statement"]) check_cc_cxx_flag([-Wempty-body], [CFLAGS="$CFLAGS -Wempty-body"]) check_cc_cxx_flag([-Wformat], [CFLAGS="$CFLAGS -Wformat"]) check_cc_cxx_flag([-Wformat-nonliteral], [CFLAGS="$CFLAGS -Wformat-nonliteral"]) check_cc_cxx_flag([-Wformat-security], [CFLAGS="$CFLAGS -Wformat-security"]) check_cc_cxx_flag([-Winit-self], [CFLAGS="$CFLAGS -Winit-self"]) check_cc_cxx_flag([-Winline], [CFLAGS="$CFLAGS -Winline"]) check_cc_cxx_flag([-Wmissing-include-dirs], [CFLAGS="$CFLAGS -Wmissing-include-dirs"]) check_cc_cxx_flag([-Wno-strict-aliasing], [CFLAGS="$CFLAGS -Wno-strict-aliasing"]) check_cc_cxx_flag([-Wno-uninitialized], [CFLAGS="$CFLAGS -Wno-uninitialized"]) check_cc_cxx_flag([-Wredundant-decls], [CFLAGS="$CFLAGS -Wredundant-decls"]) check_cc_cxx_flag([-Wreturn-type], [CFLAGS="$CFLAGS -Wreturn-type"]) check_cc_cxx_flag([-Wshadow], [CFLAGS="$CFLAGS -Wshadow"]) check_cc_cxx_flag([-Wswitch-default], [CFLAGS="$CFLAGS -Wswitch-default"]) check_cc_cxx_flag([-Wswitch-enum], [CFLAGS="$CFLAGS -Wswitch-enum"]) check_cc_cxx_flag([-Wundef], [CFLAGS="$CFLAGS -Wundef"]) check_cc_cxx_flag([-Wuninitialized], [CFLAGS="$CFLAGS -Wuninitialized"])]) mongodb-1.1.5/src/libmongoc/build/autotools/Optimizations.m40000664000175000017500000000142512673034026024013 0ustar jmikolajmikolaOPTIMIZE_CFLAGS="" OPTIMIZE_LDFLAGS="" dnl Check if we should use -Bsymbolic AS_IF([test "$enable_optimizations" != "no"], [ check_link_flag([-Wl,-Bsymbolic], [OPTIMIZE_LDFLAGS="$OPTIMIZE_LDFLAGS -Wl,-Bsymbolic"]) dnl Add the appropriate 'O' level for optimized builds. CFLAGS="$CFLAGS -O2" ]) AC_SUBST(OPTIMIZE_CFLAGS) AC_SUBST(OPTIMIZE_LDFLAGS) # Add '-g' flag to gcc to build with debug symbols. if test "$enable_debug_symbols" = "min"; then CFLAGS="$CFLAGS -g1" elif test "$enable_debug_symbols" != "no"; then CFLAGS="$CFLAGS -g" fi AS_IF([test $"enable_debug" = "no"], [CPPFLAGS="$CPPFLAGS -DBSON_DISABLE_ASSERT" CPPFLAGS="$CPPFLAGS -DBSON_DISABLE_CHECKS"]) AS_IF([test "$enable_tracing" = "yes"], [CPPFLAGS="$CPPFLAGS -DMONGOC_TRACE"]) mongodb-1.1.5/src/libmongoc/build/autotools/PlatformFlags.m40000664000175000017500000000136412673034026023705 0ustar jmikolajmikoladnl check_cc_cxx_flag is defined in build/autotools/AutoHarden.m4 dnl Ignore OpenSSL deprecation warnings on OSX AS_IF([test "$os_darwin" = "yes"], [check_cc_cxx_flag([-Wno-deprecated-declarations], [CFLAGS="$CFLAGS -Wno-deprecated-declarations"])]) dnl We know there are some cast-align issues on OSX AS_IF([test "$os_darwin" = "yes"], [check_cc_cxx_flag([-Wno-cast-align], [CFLAGS="$CFLAGS -Wno-cast-align"])]) AS_IF([test "$os_darwin" = "yes"], [check_cc_cxx_flag([-Wno-unneeded-internal-declaration], [CFLAGS="$CFLAGS -Wno-unneeded-internal-declaration"])]) dnl We know there are some cast-align issues on Solaris AS_IF([test "$os_solaris" = "yes"], [check_cc_cxx_flag([-Wno-cast-align], [CFLAGS="$CFLAGS -Wno-cast-align"])]) mongodb-1.1.5/src/libmongoc/build/autotools/PrintBuildConfiguration.m40000664000175000017500000000267112673034026025752 0ustar jmikolajmikolaAC_OUTPUT if test -n "$MONGOC_PRERELEASE_VERSION"; then cat << EOF *** IMPORTANT *** This is an unstable version of libmongoc. It is for test purposes only. Please, DO NOT use it in a production environment. It will probably crash and you will lose your data. Additionally, the API/ABI may change during the course of development. Thanks, The libmongoc team. *** END OF WARNING *** EOF fi echo " libmongoc $MONGOC_VERSION was configured with the following options: Build configuration: Enable debugging (slow) : ${enable_debug} Compile with debug symbols (slow) : ${enable_debug_symbols} Enable GCC build optimization : ${enable_optimizations} Enable automatic binary hardening : ${enable_hardening} Code coverage support : ${enable_coverage} Cross Compiling : ${enable_crosscompile} Fast counters : ${enable_rdtscp} Shared memory performance counters : ${enable_shm_counters} SASL : ${sasl_mode} SSL : ${enable_ssl} Libbson : ${with_libbson} Documentation: man : ${enable_man_pages} HTML : ${enable_html_docs} " mongodb-1.1.5/src/libmongoc/build/autotools/ReadCommandLineArguments.m40000664000175000017500000000775712673034026026030 0ustar jmikolajmikolaAC_MSG_CHECKING([whether to do a debug build]) AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug], [turn on debugging [default=no]]), [],[enable_debug="no"]) AC_MSG_RESULT([$enable_debug]) AC_MSG_CHECKING([whether to enable tracing]) AC_ARG_ENABLE(tracing, AC_HELP_STRING([--enable-tracing], [turn on tracing [default=no]]), [],[enable_tracing="no"]) AC_MSG_RESULT([$enable_tracing]) AC_MSG_CHECKING([whether to enable optimized builds]) AC_ARG_ENABLE(optimizations, AC_HELP_STRING([--enable-optimizations], [turn on build-time optimizations [default=yes]]), [enable_optimizations=$enableval], [ if test "$enable_debug" = "yes"; then enable_optimizations="no"; else enable_optimizations="yes"; fi ]) AC_MSG_RESULT([$enable_optimizations]) AC_MSG_CHECKING([whether to enable shared memory performance counters]) AC_ARG_ENABLE(shm_counters, AC_HELP_STRING([--enable-shm-counters], [turn on shared memory performance counters [default=yes]]), [],[enable_shm_counters="yes"]) AC_MSG_RESULT([$enable_shm_counters]) AC_MSG_CHECKING([whether to enable code coverage support]) AC_ARG_ENABLE(coverage, AC_HELP_STRING([--enable-coverage], [enable code coverage support [default=no]]), [], [enable_coverage="no"]) AC_MSG_RESULT([$enable_coverage]) AC_MSG_CHECKING([whether to enable debug symbols]) AC_ARG_ENABLE(debug_symbols, AC_HELP_STRING([--enable-debug-symbols=yes|no|min|full], [enable debug symbols default=no, default=yes for debug builds]), [ case "$enable_debug_symbols" in yes) enable_debug_symbols="full" ;; no|min|full) ;; *) AC_MSG_ERROR([Invalid debug symbols option: must be yes, no, min or full.]) ;; esac ], [ if test "$enable_debug" = "yes"; then enable_debug_symbols="yes"; else enable_debug_symbols="no"; fi ]) AC_MSG_RESULT([$enable_debug_symbols]) AC_ARG_ENABLE([rdtscp], [AS_HELP_STRING([--enable-rdtscp=@<:@no/yes@:>@], [Use rdtscp for per-cpu counters @<:@default=no@:>@])], [], [enable_rdtscp=no]) # use strict compiler flags only on development releases m4_define([maintainer_flags_default], [m4_ifset([MONGOC_PRERELEASE_VERSION], [yes], [no])]) AC_ARG_ENABLE([maintainer-flags], [AS_HELP_STRING([--enable-maintainer-flags=@<:@no/yes@:>@], [Use strict compiler flags @<:@default=]maintainer_flags_default[@:>@])], [], [enable_maintainer_flags=maintainer_flags_default]) # Check if we should use the bundled (git submodule) libbson AC_ARG_WITH(libbson, AC_HELP_STRING([--with-libbson=@<:@auto/system/bundled@:>@], [use system installed libbson or bundled libbson. default=auto]), [], [with_libbson=auto]) AS_IF([test "x$with_libbson" != xbundled && test "x$with_libbson" != xsystem], [with_libbson=auto]) AC_ARG_ENABLE([html-docs], [AS_HELP_STRING([--enable-html-docs=@<:@yes/no@:>@], [Build HTML documentation.])], [], [enable_html_docs=no]) AC_ARG_ENABLE([man-pages], [AS_HELP_STRING([--enable-man-pages=@<:@yes/no@:>@], [Build and install man-pages.])], [], [enable_man_pages=no]) AC_ARG_ENABLE([yelp], [AS_HELP_STRING([--enable-yelp=@<:@yes/no@:>@], [Install yelp manuals.])], [], [enable_yelp=no]) AC_ARG_ENABLE([examples], [AS_HELP_STRING([--enable-examples=@<:@yes/no@:>@], [Build MongoDB C Driver examples.])], [], [enable_examples=yes]) AC_ARG_ENABLE([tests], [AS_HELP_STRING([--enable-tests=@<:@yes/no@:>@], [Build MongoDB C Driver tests.])], [], [enable_tests=yes]) mongodb-1.1.5/src/libmongoc/build/autotools/SetupAutomake.m40000664000175000017500000000330512673034026023730 0ustar jmikolajmikolam4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) AM_PROG_CC_C_O # OS Conditionals. AM_CONDITIONAL([OS_WIN32],[test "$os_win32" = "yes"]) AM_CONDITIONAL([OS_UNIX],[test "$os_win32" = "no"]) AM_CONDITIONAL([OS_LINUX],[test "$os_linux" = "yes"]) AM_CONDITIONAL([OS_GNU],[test "$os_gnu" = "yes"]) AM_CONDITIONAL([OS_DARWIN],[test "$os_darwin" = "yes"]) AM_CONDITIONAL([OS_FREEBSD],[test "$os_freebsd" = "yes"]) AM_CONDITIONAL([OS_SOLARIS],[test "$os_solaris" = "yes"]) # Compiler Conditionals. AM_CONDITIONAL([COMPILER_GCC],[test "$c_compiler" = "gcc" && test "$cxx_compiler" = "g++"]) AM_CONDITIONAL([COMPILER_CLANG],[test "$c_compiler" = "clang" && test "$cxx_compiler" = "clang++"]) # Feature Conditionals AM_CONDITIONAL([ENABLE_DEBUG],[test "$enable_debug" = "yes"]) # C99 Features AM_CONDITIONAL([ENABLE_STDBOOL],[test "$enable_stdbool" = "yes"]) # Should we use pthreads AM_CONDITIONAL([ENABLE_PTHREADS],[test "$enable_pthreads" = "yes"]) # Should we compile the bundled libbson AM_CONDITIONAL([WITH_LIBBSON],[test "$with_libbson" = "bundled"]) # Should we avoid extra BSON_LIBS when linking (SunStudio) AM_CONDITIONAL([EXPLICIT_LIBS],[test "$with_gnu_ld" = "yes"]) # Should we build the examples. AM_CONDITIONAL([ENABLE_EXAMPLES],[test "$enable_examples" = "yes"]) # Should we build the tests. AM_CONDITIONAL([ENABLE_TESTS],[test "$enable_tests" = "yes"]) # Should we build man pages AM_CONDITIONAL([ENABLE_MAN_PAGES],[test "$enable_man_pages" = "yes"]) # Should we build HTML documentation AM_CONDITIONAL([ENABLE_HTML_DOCS],[test "$enable_html_docs" = "yes"]) AS_IF([test "$enable_html_docs" = "yes" && test -z "$YELP_BUILD"], [AC_MSG_ERROR([yelp-build must be installed to generate HTML documentation.])]) mongodb-1.1.5/src/libmongoc/build/autotools/SetupLibtool.m40000664000175000017500000000011112673034026023556 0ustar jmikolajmikolaLT_PREREQ([2.2]) AC_DISABLE_STATIC AC_LIBTOOL_WIN32_DLL AC_PROG_LIBTOOL mongodb-1.1.5/src/libmongoc/build/autotools/Versions.m40000664000175000017500000000355712673034026022762 0ustar jmikolajmikolaMONGOC_CURRENT_FILE=${srcdir}/VERSION_CURRENT MONGOC_VERSION=$(cat $MONGOC_CURRENT_FILE) MONGOC_MAJOR_VERSION=$(cut -d- -f1 $MONGOC_CURRENT_FILE | cut -d. -f1) MONGOC_MINOR_VERSION=$(cut -d- -f1 $MONGOC_CURRENT_FILE | cut -d. -f2) MONGOC_MICRO_VERSION=$(cut -d- -f1 $MONGOC_CURRENT_FILE | cut -d. -f3) MONGOC_PRERELEASE_VERSION=$(cut -s -d- -f2 $MONGOC_CURRENT_FILE) AC_SUBST(MONGOC_VERSION) AC_SUBST(MONGOC_MAJOR_VERSION) AC_SUBST(MONGOC_MINOR_VERSION) AC_SUBST(MONGOC_MICRO_VERSION) AC_SUBST(MONGOC_PRERELEASE_VERSION) MONGOC_RELEASED_FILE=${srcdir}/VERSION_RELEASED MONGOC_RELEASED_VERSION=$(cat $MONGOC_RELEASED_FILE) MONGOC_RELEASED_MAJOR_VERSION=$(cut -d- -f1 $MONGOC_RELEASED_FILE | cut -d. -f1) MONGOC_RELEASED_MINOR_VERSION=$(cut -d- -f1 $MONGOC_RELEASED_FILE | cut -d. -f2) MONGOC_RELEASED_MICRO_VERSION=$(cut -d- -f1 $MONGOC_RELEASED_FILE | cut -d. -f3) MONGOC_RELEASED_PRERELEASE_VERSION=$(cut -s -d- -f2 $MONGOC_RELEASED_FILE) AC_SUBST(MONGOC_RELEASED_VERSION) AC_SUBST(MONGOC_RELEASED_MAJOR_VERSION) AC_SUBST(MONGOC_RELEASED_MINOR_VERSION) AC_SUBST(MONGOC_RELEASED_MICRO_VERSION) AC_SUBST(MONGOC_RELEASED_PRERELEASE_VERSION) AC_MSG_NOTICE([Current version (from VERSION_CURRENT file): $MONGOC_VERSION]) if test "x$MONGOC_RELEASED_PRERELEASE_VERSION" != "x"; then AC_ERROR([RELEASED_VERSION file has prerelease version $MONGOC_RELEASED_VERSION]) fi if test "x$MONGOC_VERSION" != "x$MONGOC_RELEASED_VERSION"; then AC_MSG_NOTICE([Most recent release (from VERSION_RELEASED file): $MONGOC_RELEASED_VERSION]) if test "x$MONGOC_PRERELEASE_VERSION" = "x"; then AC_ERROR([Current version ($MONGOC_PRERELEASE_VERSION) must be a prerelease (with "-dev", "-beta", etc.) or equal to previous release]) fi fi dnl So far, we've synchronized libbson and mongoc versions. m4_define([libbson_required_version], $MONGOC_RELEASED_VERSION) m4_define([sasl_required_version], [2.1.6]) mongodb-1.1.5/src/libmongoc/build/autotools/WeakSymbols.m40000664000175000017500000000040112673034026023373 0ustar jmikolajmikolaAC_MSG_CHECKING(if weak symbols are supported) AC_LINK_IFELSE([AC_LANG_PROGRAM([[ __attribute__((weak)) void __dummy(void *x) { } void f(void *x) { __dummy(x); } ]], [[ ]] )], [AC_MSG_RESULT(yes) AC_SUBST(MONGOC_HAVE_WEAK_SYMBOLS, 1)], [AC_MSG_RESULT(no)]) mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-array-private.h0000664000175000017500000000322612673034026024041 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_ARRAY_PRIVATE_H #define MONGOC_ARRAY_PRIVATE_H #if !defined (MONGOC_I_AM_A_DRIVER) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #include BSON_BEGIN_DECLS typedef struct _mongoc_array_t mongoc_array_t; struct _mongoc_array_t { size_t len; size_t element_size; size_t allocated; void *data; }; #define _mongoc_array_append_val(a, v) _mongoc_array_append_vals(a, &v, 1) #define _mongoc_array_index(a, t, i) (((t*)(a)->data)[i]) #define _mongoc_array_clear(a) (a)->len = 0 void _mongoc_array_init (mongoc_array_t *array, size_t element_size); void _mongoc_array_copy (mongoc_array_t *dst, const mongoc_array_t *src); void _mongoc_array_append_vals (mongoc_array_t *array, const void *data, uint32_t n_elements); void _mongoc_array_destroy (mongoc_array_t *array); BSON_END_DECLS #endif /* MONGOC_ARRAY_PRIVATE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-array.c0000664000175000017500000000450612673034026022366 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "mongoc-array-private.h" void _mongoc_array_init (mongoc_array_t *array, size_t element_size) { BSON_ASSERT (array); BSON_ASSERT (element_size); array->len = 0; array->element_size = element_size; array->allocated = 128; array->data = (void *)bson_malloc0(array->allocated); } /* *-------------------------------------------------------------------------- * * _mongoc_array_copy -- * * Destroy dst and copy src into it. Both arrays must be initialized. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void _mongoc_array_copy (mongoc_array_t *dst, const mongoc_array_t *src) { _mongoc_array_destroy (dst); dst->len = src->len; dst->element_size = src->element_size; dst->allocated = src->allocated; dst->data = (void *)bson_malloc (dst->allocated); memcpy (dst->data, src->data, dst->allocated); } void _mongoc_array_destroy (mongoc_array_t *array) { if (array && array->data) { bson_free(array->data); } } void _mongoc_array_append_vals (mongoc_array_t *array, const void *data, uint32_t n_elements) { size_t len; size_t off; size_t next_size; BSON_ASSERT (array); BSON_ASSERT (data); off = array->element_size * array->len; len = (size_t)n_elements * array->element_size; if ((off + len) > array->allocated) { next_size = bson_next_power_of_two(off + len); array->data = (void *)bson_realloc(array->data, next_size); array->allocated = next_size; } memcpy((uint8_t *)array->data + off, data, len); array->len += n_elements; } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-async-cmd-private.h0000664000175000017500000000612612673034026024603 0ustar jmikolajmikola/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_ASYNC_CMD_PRIVATE_H #define MONGOC_ASYNC_CMD_PRIVATE_H #if !defined (MONGOC_I_AM_A_DRIVER) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #include #include "mongoc-client.h" #include "mongoc-async-private.h" #include "mongoc-array-private.h" #include "mongoc-buffer-private.h" #include "mongoc-rpc-private.h" #include "mongoc-stream.h" BSON_BEGIN_DECLS typedef enum { MONGOC_ASYNC_CMD_SETUP, MONGOC_ASYNC_CMD_SEND, MONGOC_ASYNC_CMD_RECV_LEN, MONGOC_ASYNC_CMD_RECV_RPC, MONGOC_ASYNC_CMD_ERROR_STATE, MONGOC_ASYNC_CMD_CANCELED_STATE, } mongoc_async_cmd_state_t; typedef struct _mongoc_async_cmd { mongoc_stream_t *stream; mongoc_async_t *async; mongoc_async_cmd_state_t state; int events; mongoc_async_cmd_setup_t setup; void *setup_ctx; mongoc_async_cmd_cb_t cb; void *data; bson_error_t error; int64_t start_time; int64_t expire_at; bson_t cmd; mongoc_buffer_t buffer; mongoc_array_t array; mongoc_iovec_t *iovec; size_t niovec; size_t bytes_to_read; mongoc_rpc_t rpc; bson_t reply; bool reply_needs_cleanup; char ns[MONGOC_NAMESPACE_MAX]; struct _mongoc_async_cmd *next; struct _mongoc_async_cmd *prev; } mongoc_async_cmd_t; mongoc_async_cmd_t * mongoc_async_cmd_new (mongoc_async_t *async, mongoc_stream_t *stream, mongoc_async_cmd_setup_t setup, void *setup_ctx, const char *dbname, const bson_t *cmd, mongoc_async_cmd_cb_t cb, void *cb_data, int32_t timeout_msec); void mongoc_async_cmd_destroy (mongoc_async_cmd_t *acmd); bool mongoc_async_cmd_run (mongoc_async_cmd_t *acmd); #ifdef MONGOC_ENABLE_SSL int mongoc_async_cmd_tls_setup (mongoc_stream_t *stream, int *events, void *ctx, int32_t timeout_msec, bson_error_t *error); #endif BSON_END_DECLS #endif /* MONGOC_ASYNC_CMD_PRIVATE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-async-cmd.c0000664000175000017500000002734112673034026023130 0ustar jmikolajmikola/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include "mongoc-client.h" #include "mongoc-async-cmd-private.h" #include "mongoc-async-private.h" #include "mongoc-error.h" #include "mongoc-opcode.h" #include "mongoc-rpc-private.h" #include "mongoc-stream-private.h" #include "mongoc-server-description-private.h" #include "utlist.h" #ifdef MONGOC_ENABLE_SSL #include "mongoc-stream-tls.h" #endif #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "async" typedef mongoc_async_cmd_result_t (*_mongoc_async_cmd_phase_t)( mongoc_async_cmd_t *cmd); mongoc_async_cmd_result_t _mongoc_async_cmd_phase_setup (mongoc_async_cmd_t *cmd); mongoc_async_cmd_result_t _mongoc_async_cmd_phase_send (mongoc_async_cmd_t *cmd); mongoc_async_cmd_result_t _mongoc_async_cmd_phase_recv_len (mongoc_async_cmd_t *cmd); mongoc_async_cmd_result_t _mongoc_async_cmd_phase_recv_rpc (mongoc_async_cmd_t *cmd); static const _mongoc_async_cmd_phase_t gMongocCMDPhases[] = { _mongoc_async_cmd_phase_setup, _mongoc_async_cmd_phase_send, _mongoc_async_cmd_phase_recv_len, _mongoc_async_cmd_phase_recv_rpc, NULL, /* no callback for MONGOC_ASYNC_CMD_ERROR_STATE */ NULL, /* no callback for MONGOC_ASYNC_CMD_CANCELED_STATE */ }; #ifdef MONGOC_ENABLE_SSL int mongoc_async_cmd_tls_setup (mongoc_stream_t *stream, int *events, void *ctx, int32_t timeout_msec, bson_error_t *error) { mongoc_stream_t *tls_stream; const char *host = (const char *)ctx; for (tls_stream = stream; tls_stream->type != MONGOC_STREAM_TLS; tls_stream = mongoc_stream_get_base_stream (tls_stream)) { } if (mongoc_stream_tls_do_handshake (tls_stream, timeout_msec)) { if (mongoc_stream_tls_check_cert (tls_stream, host)) { return 1; } else { bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, "Failed to verify TLS cert."); return -1; } } else if (mongoc_stream_tls_should_retry (tls_stream)) { *events = mongoc_stream_tls_should_read (tls_stream) ? POLLIN : POLLOUT; } else { bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, "Failed to initialize TLS state."); return -1; } return 0; } #endif bool mongoc_async_cmd_run (mongoc_async_cmd_t *acmd) { mongoc_async_cmd_result_t result; int64_t rtt; _mongoc_async_cmd_phase_t phase_callback; phase_callback = gMongocCMDPhases[acmd->state]; if (phase_callback) { result = phase_callback (acmd); } else { result = MONGOC_ASYNC_CMD_ERROR; } if (result == MONGOC_ASYNC_CMD_IN_PROGRESS) { return true; } rtt = bson_get_monotonic_time () - acmd->start_time; if (result == MONGOC_ASYNC_CMD_SUCCESS) { acmd->cb (result, &acmd->reply, rtt, acmd->data, &acmd->error); } else { /* we're in ERROR, TIMEOUT, or CANCELED */ acmd->cb (result, NULL, rtt, acmd->data, &acmd->error); } mongoc_async_cmd_destroy (acmd); return false; } void _mongoc_async_cmd_init_send (mongoc_async_cmd_t *acmd, const char *dbname) { bson_snprintf (acmd->ns, sizeof acmd->ns, "%s.$cmd", dbname); acmd->rpc.query.msg_len = 0; acmd->rpc.query.request_id = ++acmd->async->request_id; acmd->rpc.query.response_to = 0; acmd->rpc.query.opcode = MONGOC_OPCODE_QUERY; acmd->rpc.query.flags = MONGOC_QUERY_SLAVE_OK; acmd->rpc.query.collection = acmd->ns; acmd->rpc.query.skip = 0; acmd->rpc.query.n_return = -1; acmd->rpc.query.query = bson_get_data (&acmd->cmd); acmd->rpc.query.fields = NULL; _mongoc_rpc_gather (&acmd->rpc, &acmd->array); acmd->iovec = (mongoc_iovec_t *)acmd->array.data; acmd->niovec = acmd->array.len; _mongoc_rpc_swab_to_le (&acmd->rpc); } void _mongoc_async_cmd_state_start (mongoc_async_cmd_t *acmd) { if (acmd->setup) { acmd->state = MONGOC_ASYNC_CMD_SETUP; } else { acmd->state = MONGOC_ASYNC_CMD_SEND; } acmd->events = POLLOUT; } mongoc_async_cmd_t * mongoc_async_cmd_new (mongoc_async_t *async, mongoc_stream_t *stream, mongoc_async_cmd_setup_t setup, void *setup_ctx, const char *dbname, const bson_t *cmd, mongoc_async_cmd_cb_t cb, void *cb_data, int32_t timeout_msec) { mongoc_async_cmd_t *acmd; mongoc_async_cmd_t *tmp; bool found = false; BSON_ASSERT (cmd); BSON_ASSERT (dbname); BSON_ASSERT (stream); acmd = (mongoc_async_cmd_t *)bson_malloc0 (sizeof (*acmd)); acmd->async = async; acmd->expire_at = bson_get_monotonic_time () + (int64_t) timeout_msec * 1000; acmd->stream = stream; acmd->setup = setup; acmd->setup_ctx = setup_ctx; acmd->cb = cb; acmd->data = cb_data; bson_copy_to (cmd, &acmd->cmd); _mongoc_array_init (&acmd->array, sizeof (mongoc_iovec_t)); _mongoc_buffer_init (&acmd->buffer, NULL, 0, NULL, NULL); _mongoc_async_cmd_init_send (acmd, dbname); _mongoc_async_cmd_state_start (acmd); /* slot the cmd into the right place in the expiration list */ { async->ncmds++; DL_FOREACH (async->cmds, tmp) { if (tmp->expire_at >= acmd->expire_at) { DL_PREPEND_ELEM (async->cmds, tmp, acmd); found = true; break; } } if (! found) { DL_APPEND (async->cmds, acmd); } } return acmd; } void mongoc_async_cmd_destroy (mongoc_async_cmd_t *acmd) { BSON_ASSERT (acmd); DL_DELETE (acmd->async->cmds, acmd); acmd->async->ncmds--; bson_destroy (&acmd->cmd); if (acmd->reply_needs_cleanup) { bson_destroy (&acmd->reply); } _mongoc_array_destroy (&acmd->array); _mongoc_buffer_destroy (&acmd->buffer); bson_free (acmd); } mongoc_async_cmd_result_t _mongoc_async_cmd_phase_setup (mongoc_async_cmd_t *acmd) { int64_t now; int64_t timeout_msec; now = bson_get_monotonic_time (); timeout_msec = (acmd->expire_at - now) / 1000; BSON_ASSERT (timeout_msec < INT32_MAX); switch (acmd->setup (acmd->stream, &acmd->events, acmd->setup_ctx, (int32_t) timeout_msec, &acmd->error)) { case -1: return MONGOC_ASYNC_CMD_ERROR; break; case 0: break; case 1: acmd->state = MONGOC_ASYNC_CMD_SEND; acmd->events = POLLOUT; break; default: abort(); } return MONGOC_ASYNC_CMD_IN_PROGRESS; } mongoc_async_cmd_result_t _mongoc_async_cmd_phase_send (mongoc_async_cmd_t *acmd) { ssize_t bytes; bytes = mongoc_stream_writev (acmd->stream, acmd->iovec, acmd->niovec, 0); if (bytes < 0) { bson_set_error (&acmd->error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, "Failed to write rpc bytes."); return MONGOC_ASYNC_CMD_ERROR; } while (bytes) { if (acmd->iovec->iov_len < (size_t)bytes) { bytes -= acmd->iovec->iov_len; acmd->iovec++; acmd->niovec--; } else { acmd->iovec->iov_base = ((char *)acmd->iovec->iov_base) + bytes; acmd->iovec->iov_len -= bytes; bytes = 0; } } acmd->state = MONGOC_ASYNC_CMD_RECV_LEN; acmd->bytes_to_read = 4; acmd->events = POLLIN; acmd->start_time = bson_get_monotonic_time (); return MONGOC_ASYNC_CMD_IN_PROGRESS; } mongoc_async_cmd_result_t _mongoc_async_cmd_phase_recv_len (mongoc_async_cmd_t *acmd) { ssize_t bytes = _mongoc_buffer_try_append_from_stream (&acmd->buffer, acmd->stream, acmd->bytes_to_read, 0, &acmd->error); uint32_t msg_len; if (bytes < 0) { bson_set_error (&acmd->error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, "Failed to receive length header from server."); return MONGOC_ASYNC_CMD_ERROR; } if (bytes == 0) { bson_set_error (&acmd->error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, "Server closed connection."); return MONGOC_ASYNC_CMD_ERROR; } acmd->bytes_to_read -= bytes; if (!acmd->bytes_to_read) { memcpy (&msg_len, acmd->buffer.data, 4); msg_len = BSON_UINT32_FROM_LE (msg_len); if ((msg_len < 16) || (msg_len > MONGOC_DEFAULT_MAX_MSG_SIZE)) { bson_set_error (&acmd->error, MONGOC_ERROR_PROTOCOL, MONGOC_ERROR_PROTOCOL_INVALID_REPLY, "Invalid reply from server."); return MONGOC_ASYNC_CMD_ERROR; } acmd->bytes_to_read = msg_len - 4; acmd->state = MONGOC_ASYNC_CMD_RECV_RPC; return _mongoc_async_cmd_phase_recv_rpc (acmd); } return MONGOC_ASYNC_CMD_IN_PROGRESS; } mongoc_async_cmd_result_t _mongoc_async_cmd_phase_recv_rpc (mongoc_async_cmd_t *acmd) { ssize_t bytes = _mongoc_buffer_try_append_from_stream (&acmd->buffer, acmd->stream, acmd->bytes_to_read, 0, &acmd->error); if (bytes < 0) { bson_set_error (&acmd->error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, "Failed to receive rpc bytes from server."); return MONGOC_ASYNC_CMD_ERROR; } if (bytes == 0) { bson_set_error (&acmd->error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, "Server closed connection."); return MONGOC_ASYNC_CMD_ERROR; } acmd->bytes_to_read -= bytes; if (!acmd->bytes_to_read) { if (!_mongoc_rpc_scatter (&acmd->rpc, acmd->buffer.data, acmd->buffer.len)) { bson_set_error (&acmd->error, MONGOC_ERROR_PROTOCOL, MONGOC_ERROR_PROTOCOL_INVALID_REPLY, "Invalid reply from server."); return MONGOC_ASYNC_CMD_ERROR; } _mongoc_rpc_swab_from_le (&acmd->rpc); if (acmd->rpc.header.opcode != MONGOC_OPCODE_REPLY) { bson_set_error (&acmd->error, MONGOC_ERROR_PROTOCOL, MONGOC_ERROR_PROTOCOL_INVALID_REPLY, "Invalid reply from server."); return MONGOC_ASYNC_CMD_ERROR; } if (!_mongoc_rpc_reply_get_first (&acmd->rpc.reply, &acmd->reply)) { bson_set_error (&acmd->error, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, "Failed to decode reply BSON document."); return MONGOC_ASYNC_CMD_ERROR; } acmd->reply_needs_cleanup = true; return MONGOC_ASYNC_CMD_SUCCESS; } return MONGOC_ASYNC_CMD_IN_PROGRESS; } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-async-private.h0000664000175000017500000000501312673034026024034 0ustar jmikolajmikola/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_ASYNC_PRIVATE_H #define MONGOC_ASYNC_PRIVATE_H #if !defined (MONGOC_I_AM_A_DRIVER) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #include #include "mongoc-stream.h" BSON_BEGIN_DECLS struct _mongoc_async_cmd; typedef struct _mongoc_async { struct _mongoc_async_cmd *cmds; size_t ncmds; uint32_t request_id; } mongoc_async_t; typedef enum { MONGOC_ASYNC_CMD_IN_PROGRESS, MONGOC_ASYNC_CMD_SUCCESS, MONGOC_ASYNC_CMD_ERROR, MONGOC_ASYNC_CMD_TIMEOUT, } mongoc_async_cmd_result_t; typedef void (*mongoc_async_cmd_cb_t)(mongoc_async_cmd_result_t result, const bson_t *bson, int64_t rtt_msec, void *data, bson_error_t *error); typedef int (*mongoc_async_cmd_setup_t)(mongoc_stream_t *stream, int *events, void *ctx, int32_t timeout_msec, bson_error_t *error); mongoc_async_t * mongoc_async_new (); void mongoc_async_destroy (mongoc_async_t *async); bool mongoc_async_run (mongoc_async_t *async, int32_t timeout_msec); struct _mongoc_async_cmd * mongoc_async_cmd (mongoc_async_t *async, mongoc_stream_t *stream, mongoc_async_cmd_setup_t setup, void *setup_ctx, const char *dbname, const bson_t *cmd, mongoc_async_cmd_cb_t cb, void *cb_data, int32_t timeout_msec); BSON_END_DECLS #endif /* MONGOC_ASYNC_PRIVATE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-async.c0000664000175000017500000001004012673034026022353 0ustar jmikolajmikola/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include "mongoc-async-private.h" #include "mongoc-async-cmd-private.h" #include "utlist.h" #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "async" mongoc_async_cmd_t * mongoc_async_cmd (mongoc_async_t *async, mongoc_stream_t *stream, mongoc_async_cmd_setup_t setup, void *setup_ctx, const char *dbname, const bson_t *cmd, mongoc_async_cmd_cb_t cb, void *cb_data, int32_t timeout_msec) { return mongoc_async_cmd_new (async, stream, setup, setup_ctx, dbname, cmd, cb, cb_data, timeout_msec); } mongoc_async_t * mongoc_async_new () { mongoc_async_t *async = (mongoc_async_t *)bson_malloc0 (sizeof (*async)); return async; } void mongoc_async_destroy (mongoc_async_t *async) { mongoc_async_cmd_t *acmd, *tmp; DL_FOREACH_SAFE (async->cmds, acmd, tmp) { mongoc_async_cmd_destroy (acmd); } bson_free (async); } bool mongoc_async_run (mongoc_async_t *async, int32_t timeout_msec) { mongoc_async_cmd_t *acmd, *tmp; mongoc_stream_poll_t *poller = NULL; int i; ssize_t nactive = 0; int64_t now; int64_t expire_at = 0; size_t poll_size = 0; for (;;) { now = bson_get_monotonic_time (); if (expire_at == 0) { if (timeout_msec >= 0) { expire_at = now + ((int64_t) timeout_msec * 1000); } else { expire_at = -1; } } else if (timeout_msec >= 0) { timeout_msec = (expire_at - now) / 1000; } if (now > expire_at) { break; } DL_FOREACH_SAFE (async->cmds, acmd, tmp) { /* async commands are sorted by expire_at */ if (now > acmd->expire_at) { acmd->cb (MONGOC_ASYNC_CMD_TIMEOUT, NULL, (now - acmd->start_time), acmd->data, &acmd->error); mongoc_async_cmd_destroy (acmd); } else { break; } } if (!async->ncmds) { break; } if (poll_size < async->ncmds) { poller = (mongoc_stream_poll_t *)bson_realloc (poller, sizeof (*poller) * async->ncmds); poll_size = async->ncmds; } i = 0; DL_FOREACH (async->cmds, acmd) { poller[i].stream = acmd->stream; poller[i].events = acmd->events; poller[i].revents = 0; i++; } if (timeout_msec >= 0) { timeout_msec = BSON_MIN (timeout_msec, (async->cmds->expire_at - now) / 1000); } else { timeout_msec = (async->cmds->expire_at - now) / 1000; } nactive = mongoc_stream_poll (poller, async->ncmds, timeout_msec); if (nactive) { i = 0; DL_FOREACH_SAFE (async->cmds, acmd, tmp) { if (poller[i].revents & (POLLERR | POLLHUP)) { acmd->state = MONGOC_ASYNC_CMD_ERROR_STATE; } if (acmd->state == MONGOC_ASYNC_CMD_ERROR_STATE || (poller[i].revents & poller[i].events)) { mongoc_async_cmd_run (acmd); nactive--; if (!nactive) { break; } } i++; } } } if (poll_size) { bson_free (poller); } return async->ncmds; } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-b64-private.h0000664000175000017500000000230412673034026023312 0ustar jmikolajmikola/* * Copyright 2014 MongoDB Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_B64_PRIVATE_H #define MONGOC_B64_PRIVATE_H #if !defined (MONGOC_I_AM_A_DRIVER) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #include #include "mongoc-config.h" int mongoc_b64_ntop (uint8_t const *src, size_t srclength, char *target, size_t targsize); void mongoc_b64_initialize_rmap (void); #ifdef MONGOC_ENABLE_SSL int mongoc_b64_pton (char const *src, uint8_t *target, size_t targsize); #endif #endif /* MONGOC_B64_PRIVATE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-b64.c0000664000175000017500000004050512673034026021642 0ustar jmikolajmikola/* * Copyright (c) 1996, 1998 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. */ /* * Portions Copyright (c) 1995 by International Business Machines, Inc. * * International Business Machines, Inc. (hereinafter called IBM) grants * permission under its copyrights to use, copy, modify, and distribute this * Software with or without fee, provided that the above copyright notice and * all paragraphs of this notice appear in all copies, and that the name of IBM * not be used in connection with the marketing of any product incorporating * the Software or modifications thereof, without specific, written prior * permission. * * To the extent it has a right to do so, IBM grants an immunity from suit * under its patents, if any, for the use, sale or manufacture of products to * the extent that such products are used for performing Domain Name System * dynamic updates in TCP/IP networks by means of the Software. No immunity is * granted for any product per se or for any other function of any product. * * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. */ #include "mongoc-b64-private.h" #define Assert(Cond) if (!(Cond)) abort () static const char Base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; static const char Pad64 = '='; /* (From RFC1521 and draft-ietf-dnssec-secext-03.txt) * The following encoding technique is taken from RFC 1521 by Borenstein * and Freed. It is reproduced here in a slightly edited form for * convenience. * * A 65-character subset of US-ASCII is used, enabling 6 bits to be * represented per printable character. (The extra 65th character, "=", * is used to signify a special processing function.) * * The encoding process represents 24-bit groups of input bits as output * strings of 4 encoded characters. Proceeding from left to right, a * 24-bit input group is formed by concatenating 3 8-bit input groups. * These 24 bits are then treated as 4 concatenated 6-bit groups, each * of which is translated into a single digit in the base64 alphabet. * * Each 6-bit group is used as an index into an array of 64 printable * characters. The character referenced by the index is placed in the * output string. * * Table 1: The Base64 Alphabet * * Value Encoding Value Encoding Value Encoding Value Encoding * 0 A 17 R 34 i 51 z * 1 B 18 S 35 j 52 0 * 2 C 19 T 36 k 53 1 * 3 D 20 U 37 l 54 2 * 4 E 21 V 38 m 55 3 * 5 F 22 W 39 n 56 4 * 6 G 23 X 40 o 57 5 * 7 H 24 Y 41 p 58 6 * 8 I 25 Z 42 q 59 7 * 9 J 26 a 43 r 60 8 * 10 K 27 b 44 s 61 9 * 11 L 28 c 45 t 62 + * 12 M 29 d 46 u 63 / * 13 N 30 e 47 v * 14 O 31 f 48 w (pad) = * 15 P 32 g 49 x * 16 Q 33 h 50 y * * Special processing is performed if fewer than 24 bits are available * at the end of the data being encoded. A full encoding quantum is * always completed at the end of a quantity. When fewer than 24 input * bits are available in an input group, zero bits are added (on the * right) to form an integral number of 6-bit groups. Padding at the * end of the data is performed using the '=' character. * * Since all base64 input is an integral number of octets, only the * following cases can arise: * * (1) the final quantum of encoding input is an integral * multiple of 24 bits; here, the final unit of encoded * output will be an integral multiple of 4 characters * with no "=" padding, * (2) the final quantum of encoding input is exactly 8 bits; * here, the final unit of encoded output will be two * characters followed by two "=" padding characters, or * (3) the final quantum of encoding input is exactly 16 bits; * here, the final unit of encoded output will be three * characters followed by one "=" padding character. */ int mongoc_b64_ntop (uint8_t const *src, size_t srclength, char *target, size_t targsize) { size_t datalength = 0; uint8_t input[3]; uint8_t output[4]; size_t i; while (2 < srclength) { input[0] = *src++; input[1] = *src++; input[2] = *src++; srclength -= 3; output[0] = input[0] >> 2; output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); output[3] = input[2] & 0x3f; Assert (output[0] < 64); Assert (output[1] < 64); Assert (output[2] < 64); Assert (output[3] < 64); if (datalength + 4 > targsize) { return -1; } target[datalength++] = Base64[output[0]]; target[datalength++] = Base64[output[1]]; target[datalength++] = Base64[output[2]]; target[datalength++] = Base64[output[3]]; } /* Now we worry about padding. */ if (0 != srclength) { /* Get what's left. */ input[0] = input[1] = input[2] = '\0'; for (i = 0; i < srclength; i++) { input[i] = *src++; } output[0] = input[0] >> 2; output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); Assert (output[0] < 64); Assert (output[1] < 64); Assert (output[2] < 64); if (datalength + 4 > targsize) { return -1; } target[datalength++] = Base64[output[0]]; target[datalength++] = Base64[output[1]]; if (srclength == 1) { target[datalength++] = Pad64; } else{ target[datalength++] = Base64[output[2]]; } target[datalength++] = Pad64; } if (datalength >= targsize) { return -1; } target[datalength] = '\0'; /* Returned value doesn't count \0. */ return (int)datalength; } #ifdef MONGOC_ENABLE_SSL /* (From RFC1521 and draft-ietf-dnssec-secext-03.txt) The following encoding technique is taken from RFC 1521 by Borenstein and Freed. It is reproduced here in a slightly edited form for convenience. A 65-character subset of US-ASCII is used, enabling 6 bits to be represented per printable character. (The extra 65th character, "=", is used to signify a special processing function.) The encoding process represents 24-bit groups of input bits as output strings of 4 encoded characters. Proceeding from left to right, a 24-bit input group is formed by concatenating 3 8-bit input groups. These 24 bits are then treated as 4 concatenated 6-bit groups, each of which is translated into a single digit in the base64 alphabet. Each 6-bit group is used as an index into an array of 64 printable characters. The character referenced by the index is placed in the output string. Table 1: The Base64 Alphabet Value Encoding Value Encoding Value Encoding Value Encoding 0 A 17 R 34 i 51 z 1 B 18 S 35 j 52 0 2 C 19 T 36 k 53 1 3 D 20 U 37 l 54 2 4 E 21 V 38 m 55 3 5 F 22 W 39 n 56 4 6 G 23 X 40 o 57 5 7 H 24 Y 41 p 58 6 8 I 25 Z 42 q 59 7 9 J 26 a 43 r 60 8 10 K 27 b 44 s 61 9 11 L 28 c 45 t 62 + 12 M 29 d 46 u 63 / 13 N 30 e 47 v 14 O 31 f 48 w (pad) = 15 P 32 g 49 x 16 Q 33 h 50 y Special processing is performed if fewer than 24 bits are available at the end of the data being encoded. A full encoding quantum is always completed at the end of a quantity. When fewer than 24 input bits are available in an input group, zero bits are added (on the right) to form an integral number of 6-bit groups. Padding at the end of the data is performed using the '=' character. Since all base64 input is an integral number of octets, only the following cases can arise: (1) the final quantum of encoding input is an integral multiple of 24 bits; here, the final unit of encoded output will be an integral multiple of 4 characters with no "=" padding, (2) the final quantum of encoding input is exactly 8 bits; here, the final unit of encoded output will be two characters followed by two "=" padding characters, or (3) the final quantum of encoding input is exactly 16 bits; here, the final unit of encoded output will be three characters followed by one "=" padding character. */ /* skips all whitespace anywhere. converts characters, four at a time, starting at (or after) src from base - 64 numbers into three 8 bit bytes in the target area. it returns the number of data bytes stored at the target, or -1 on error. */ static int mongoc_b64rmap_initialized = 0; static uint8_t mongoc_b64rmap[256]; static const uint8_t mongoc_b64rmap_special = 0xf0; static const uint8_t mongoc_b64rmap_end = 0xfd; static const uint8_t mongoc_b64rmap_space = 0xfe; static const uint8_t mongoc_b64rmap_invalid = 0xff; /** * Initializing the reverse map is not thread safe. * Which is fine for NSD. For now... **/ void mongoc_b64_initialize_rmap (void) { int i; unsigned char ch; /* Null: end of string, stop parsing */ mongoc_b64rmap[0] = mongoc_b64rmap_end; for (i = 1; i < 256; ++i) { ch = (unsigned char)i; /* Whitespaces */ if (isspace(ch)) mongoc_b64rmap[i] = mongoc_b64rmap_space; /* Padding: stop parsing */ else if (ch == Pad64) mongoc_b64rmap[i] = mongoc_b64rmap_end; /* Non-base64 char */ else mongoc_b64rmap[i] = mongoc_b64rmap_invalid; } /* Fill reverse mapping for base64 chars */ for (i = 0; Base64[i] != '\0'; ++i) mongoc_b64rmap[(uint8_t)Base64[i]] = i; mongoc_b64rmap_initialized = 1; } static int mongoc_b64_pton_do(char const *src, uint8_t *target, size_t targsize) { int tarindex, state, ch; uint8_t ofs; state = 0; tarindex = 0; while (1) { ch = *src++; ofs = mongoc_b64rmap[ch]; if (ofs >= mongoc_b64rmap_special) { /* Ignore whitespaces */ if (ofs == mongoc_b64rmap_space) continue; /* End of base64 characters */ if (ofs == mongoc_b64rmap_end) break; /* A non-base64 character. */ return (-1); } switch (state) { case 0: if ((size_t)tarindex >= targsize) return (-1); target[tarindex] = ofs << 2; state = 1; break; case 1: if ((size_t)tarindex + 1 >= targsize) return (-1); target[tarindex] |= ofs >> 4; target[tarindex+1] = (ofs & 0x0f) << 4 ; tarindex++; state = 2; break; case 2: if ((size_t)tarindex + 1 >= targsize) return (-1); target[tarindex] |= ofs >> 2; target[tarindex+1] = (ofs & 0x03) << 6; tarindex++; state = 3; break; case 3: if ((size_t)tarindex >= targsize) return (-1); target[tarindex] |= ofs; tarindex++; state = 0; break; default: abort(); } } /* * We are done decoding Base-64 chars. Let's see if we ended * on a byte boundary, and/or with erroneous trailing characters. */ if (ch == Pad64) { /* We got a pad char. */ ch = *src++; /* Skip it, get next. */ switch (state) { case 0: /* Invalid = in first position */ case 1: /* Invalid = in second position */ return (-1); case 2: /* Valid, means one byte of info */ /* Skip any number of spaces. */ for ((void)NULL; ch != '\0'; ch = *src++) if (mongoc_b64rmap[ch] != mongoc_b64rmap_space) break; /* Make sure there is another trailing = sign. */ if (ch != Pad64) return (-1); ch = *src++; /* Skip the = */ /* Fall through to "single trailing =" case. */ /* FALLTHROUGH */ case 3: /* Valid, means two bytes of info */ /* * We know this char is an =. Is there anything but * whitespace after it? */ for ((void)NULL; ch != '\0'; ch = *src++) if (mongoc_b64rmap[ch] != mongoc_b64rmap_space) return (-1); /* * Now make sure for cases 2 and 3 that the "extra" * bits that slopped past the last full byte were * zeros. If we don't check them, they become a * subliminal channel. */ if (target[tarindex] != 0) return (-1); default: break; } } else { /* * We ended by seeing the end of the string. Make sure we * have no partial bytes lying around. */ if (state != 0) return (-1); } return (tarindex); } static int mongoc_b64_pton_len(char const *src) { int tarindex, state, ch; uint8_t ofs; state = 0; tarindex = 0; while (1) { ch = *src++; ofs = mongoc_b64rmap[ch]; if (ofs >= mongoc_b64rmap_special) { /* Ignore whitespaces */ if (ofs == mongoc_b64rmap_space) continue; /* End of base64 characters */ if (ofs == mongoc_b64rmap_end) break; /* A non-base64 character. */ return (-1); } switch (state) { case 0: state = 1; break; case 1: tarindex++; state = 2; break; case 2: tarindex++; state = 3; break; case 3: tarindex++; state = 0; break; default: abort(); } } /* * We are done decoding Base-64 chars. Let's see if we ended * on a byte boundary, and/or with erroneous trailing characters. */ if (ch == Pad64) { /* We got a pad char. */ ch = *src++; /* Skip it, get next. */ switch (state) { case 0: /* Invalid = in first position */ case 1: /* Invalid = in second position */ return (-1); case 2: /* Valid, means one byte of info */ /* Skip any number of spaces. */ for ((void)NULL; ch != '\0'; ch = *src++) if (mongoc_b64rmap[ch] != mongoc_b64rmap_space) break; /* Make sure there is another trailing = sign. */ if (ch != Pad64) return (-1); ch = *src++; /* Skip the = */ /* Fall through to "single trailing =" case. */ /* FALLTHROUGH */ case 3: /* Valid, means two bytes of info */ /* * We know this char is an =. Is there anything but * whitespace after it? */ for ((void)NULL; ch != '\0'; ch = *src++) if (mongoc_b64rmap[ch] != mongoc_b64rmap_space) return (-1); default: break; } } else { /* * We ended by seeing the end of the string. Make sure we * have no partial bytes lying around. */ if (state != 0) return (-1); } return (tarindex); } int mongoc_b64_pton(char const *src, uint8_t *target, size_t targsize) { if (!mongoc_b64rmap_initialized) mongoc_b64_initialize_rmap (); if (target) return mongoc_b64_pton_do (src, target, targsize); else return mongoc_b64_pton_len (src); } #endif /* MONGOC_ENABLE_SSL */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-buffer-private.h0000664000175000017500000000462512673034026024200 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_BUFFER_PRIVATE_H #define MONGOC_BUFFER_PRIVATE_H #if !defined (MONGOC_I_AM_A_DRIVER) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #include #include "mongoc-stream.h" BSON_BEGIN_DECLS typedef struct _mongoc_buffer_t mongoc_buffer_t; struct _mongoc_buffer_t { uint8_t *data; size_t datalen; off_t off; size_t len; bson_realloc_func realloc_func; void *realloc_data; }; void _mongoc_buffer_init (mongoc_buffer_t *buffer, uint8_t *buf, size_t buflen, bson_realloc_func realloc_func, void *realloc_data); bool _mongoc_buffer_append_from_stream (mongoc_buffer_t *buffer, mongoc_stream_t *stream, size_t size, int32_t timeout_msec, bson_error_t *error); ssize_t _mongoc_buffer_try_append_from_stream (mongoc_buffer_t *buffer, mongoc_stream_t *stream, size_t size, int32_t timeout_msec, bson_error_t *error); ssize_t _mongoc_buffer_fill (mongoc_buffer_t *buffer, mongoc_stream_t *stream, size_t min_bytes, int32_t timeout_msec, bson_error_t *error); void _mongoc_buffer_destroy (mongoc_buffer_t *buffer); void _mongoc_buffer_clear (mongoc_buffer_t *buffer, bool zero); BSON_END_DECLS #endif /* MONGOC_BUFFER_PRIVATE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-buffer.c0000664000175000017500000002163012673034026022516 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include "mongoc-error.h" #include "mongoc-buffer-private.h" #include "mongoc-trace.h" #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "buffer" #ifndef MONGOC_BUFFER_DEFAULT_SIZE # define MONGOC_BUFFER_DEFAULT_SIZE 1024 #endif #define SPACE_FOR(_b, _sz) (((ssize_t)(_b)->datalen - (ssize_t)(_b)->off - (ssize_t)(_b)->len) >= (ssize_t)(_sz)) /** * _mongoc_buffer_init: * @buffer: A mongoc_buffer_t to initialize. * @buf: A data buffer to attach to @buffer. * @buflen: The size of @buflen. * @realloc_func: A function to resize @buf. * * Initializes @buffer for use. If additional space is needed by @buffer, then * @realloc_func will be called to resize @buf. * * @buffer takes ownership of @buf and will realloc it to zero bytes when * cleaning up the data structure. */ void _mongoc_buffer_init (mongoc_buffer_t *buffer, uint8_t *buf, size_t buflen, bson_realloc_func realloc_func, void *realloc_data) { BSON_ASSERT (buffer); BSON_ASSERT (buflen || !buf); if (!realloc_func) { realloc_func = bson_realloc_ctx; } if (!buflen) { buflen = MONGOC_BUFFER_DEFAULT_SIZE; } if (!buf) { buf = (uint8_t *)realloc_func (NULL, buflen, NULL); } memset (buffer, 0, sizeof *buffer); buffer->data = buf; buffer->datalen = buflen; buffer->len = 0; buffer->off = 0; buffer->realloc_func = realloc_func; buffer->realloc_data = realloc_data; } /** * _mongoc_buffer_destroy: * @buffer: A mongoc_buffer_t. * * Cleanup after @buffer and release any allocated resources. */ void _mongoc_buffer_destroy (mongoc_buffer_t *buffer) { BSON_ASSERT (buffer); if (buffer->data && buffer->realloc_func) { buffer->realloc_func (buffer->data, 0, buffer->realloc_data); } memset(buffer, 0, sizeof *buffer); } /** * _mongoc_buffer_clear: * @buffer: A mongoc_buffer_t. * @zero: If the memory should be zeroed. * * Clears a buffers contents and resets it to initial state. You can request * that the memory is zeroed, which might be useful if you know the contents * contain security related information. */ void _mongoc_buffer_clear (mongoc_buffer_t *buffer, bool zero) { BSON_ASSERT (buffer); if (zero) { memset(buffer->data, 0, buffer->datalen); } buffer->off = 0; buffer->len = 0; } /** * mongoc_buffer_append_from_stream: * @buffer; A mongoc_buffer_t. * @stream: The stream to read from. * @size: The number of bytes to read. * @timeout_msec: The number of milliseconds to wait or -1 for the default * @error: A location for a bson_error_t, or NULL. * * Reads from stream @size bytes and stores them in @buffer. This can be used * in conjunction with reading RPCs from a stream. You read from the stream * into this buffer and then scatter the buffer into the RPC. * * Returns: true if successful; otherwise false and @error is set. */ bool _mongoc_buffer_append_from_stream (mongoc_buffer_t *buffer, mongoc_stream_t *stream, size_t size, int32_t timeout_msec, bson_error_t *error) { uint8_t *buf; ssize_t ret; ENTRY; BSON_ASSERT (buffer); BSON_ASSERT (stream); BSON_ASSERT (size); BSON_ASSERT (buffer->datalen); BSON_ASSERT ((buffer->datalen + size) < INT_MAX); if (!SPACE_FOR (buffer, size)) { if (buffer->len) { memmove(&buffer->data[0], &buffer->data[buffer->off], buffer->len); } buffer->off = 0; if (!SPACE_FOR (buffer, size)) { buffer->datalen = bson_next_power_of_two (size + buffer->len + buffer->off); buffer->data = (uint8_t *)buffer->realloc_func (buffer->data, buffer->datalen, NULL); } } buf = &buffer->data[buffer->off + buffer->len]; BSON_ASSERT ((buffer->off + buffer->len + size) <= buffer->datalen); ret = mongoc_stream_read (stream, buf, size, size, timeout_msec); if (ret != size) { bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, "Failed to read %"PRIu64" bytes from socket within %d milliseconds.", (uint64_t)size, (int)timeout_msec); RETURN (false); } buffer->len += ret; RETURN (true); } /** * _mongoc_buffer_fill: * @buffer: A mongoc_buffer_t. * @stream: A stream to read from. * @min_bytes: The minumum number of bytes to read. * @error: A location for a bson_error_t or NULL. * * Attempts to fill the entire buffer, or at least @min_bytes. * * Returns: The number of buffered bytes, or -1 on failure. */ ssize_t _mongoc_buffer_fill (mongoc_buffer_t *buffer, mongoc_stream_t *stream, size_t min_bytes, int32_t timeout_msec, bson_error_t *error) { ssize_t ret; size_t avail_bytes; ENTRY; BSON_ASSERT (buffer); BSON_ASSERT (stream); BSON_ASSERT (buffer->data); BSON_ASSERT (buffer->datalen); if (min_bytes <= buffer->len) { RETURN (buffer->len); } min_bytes -= buffer->len; if (buffer->len) { memmove (&buffer->data[0], &buffer->data[buffer->off], buffer->len); } buffer->off = 0; if (!SPACE_FOR (buffer, min_bytes)) { buffer->datalen = bson_next_power_of_two (buffer->len + min_bytes); buffer->data = (uint8_t *)buffer->realloc_func (buffer->data, buffer->datalen, buffer->realloc_data); } avail_bytes = buffer->datalen - buffer->len; ret = mongoc_stream_read (stream, &buffer->data[buffer->off + buffer->len], avail_bytes, min_bytes, timeout_msec); if (ret == -1) { bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, "Failed to buffer %u bytes within %d milliseconds.", (unsigned)min_bytes, (int)timeout_msec); RETURN (-1); } buffer->len += ret; if (buffer->len < min_bytes) { bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, "Could only buffer %u of %u bytes in %d milliseconds.", (unsigned)buffer->len, (unsigned)min_bytes, (int)timeout_msec); RETURN (-1); } RETURN (buffer->len); } /** * mongoc_buffer_try_append_from_stream: * @buffer; A mongoc_buffer_t. * @stream: The stream to read from. * @size: The number of bytes to read. * @timeout_msec: The number of milliseconds to wait or -1 for the default * @error: A location for a bson_error_t, or NULL. * * Reads from stream @size bytes and stores them in @buffer. This can be used * in conjunction with reading RPCs from a stream. You read from the stream * into this buffer and then scatter the buffer into the RPC. * * Returns: bytes read if successful; otherwise -1 and @error is set. */ ssize_t _mongoc_buffer_try_append_from_stream (mongoc_buffer_t *buffer, mongoc_stream_t *stream, size_t size, int32_t timeout_msec, bson_error_t *error) { uint8_t *buf; ssize_t ret; ENTRY; BSON_ASSERT (buffer); BSON_ASSERT (stream); BSON_ASSERT (size); BSON_ASSERT (buffer->datalen); BSON_ASSERT ((buffer->datalen + size) < INT_MAX); if (!SPACE_FOR (buffer, size)) { if (buffer->len) { memmove(&buffer->data[0], &buffer->data[buffer->off], buffer->len); } buffer->off = 0; if (!SPACE_FOR (buffer, size)) { buffer->datalen = bson_next_power_of_two (size + buffer->len + buffer->off); buffer->data = (uint8_t *)buffer->realloc_func (buffer->data, buffer->datalen, NULL); } } buf = &buffer->data[buffer->off + buffer->len]; BSON_ASSERT ((buffer->off + buffer->len + size) <= buffer->datalen); ret = mongoc_stream_read (stream, buf, size, 0, timeout_msec); if (ret > 0) { buffer->len += ret; } RETURN (ret); } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-bulk-operation-private.h0000664000175000017500000000355012673034026025656 0ustar jmikolajmikola/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_BULK_OPERATION_PRIVATE_H #define MONGOC_BULK_OPERATION_PRIVATE_H #if !defined (MONGOC_I_AM_A_DRIVER) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #include "mongoc-array-private.h" #include "mongoc-client.h" #include "mongoc-write-command-private.h" BSON_BEGIN_DECLS struct _mongoc_bulk_operation_t { char *database; char *collection; mongoc_client_t *client; mongoc_write_concern_t *write_concern; mongoc_bulk_write_flags_t flags; uint32_t hint; mongoc_array_t commands; mongoc_write_result_t result; bool executed; }; mongoc_bulk_operation_t *_mongoc_bulk_operation_new (mongoc_client_t *client, const char *database, const char *collection, mongoc_bulk_write_flags_t flags, const mongoc_write_concern_t *write_concern); BSON_END_DECLS #endif /* MONGOC_BULK_OPERATION_PRIVATE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-bulk-operation.c0000664000175000017500000003610612673034026024204 0ustar jmikolajmikola/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "mongoc-bulk-operation.h" #include "mongoc-bulk-operation-private.h" #include "mongoc-client-private.h" #include "mongoc-error.h" #include "mongoc-trace.h" #include "mongoc-write-concern-private.h" /* * This is the implementation of both write commands and bulk write commands. * They are all implemented as one contiguous set since we'd like to cut down * on code duplication here. * * This implementation is currently naive. * * Some interesting optimizations might be: * * - If unordered mode, send operations as we get them instead of waiting * for execute() to be called. This could save us memcpy()'s too. * - If there is no acknowledgement desired, keep a count of how many * replies we need and ask the socket layer to skip that many bytes * when reading. * - Try to use iovec to send write commands with subdocuments rather than * copying them into the write command document. */ mongoc_bulk_operation_t * mongoc_bulk_operation_new (bool ordered) { mongoc_bulk_operation_t *bulk; bulk = (mongoc_bulk_operation_t *)bson_malloc0 (sizeof *bulk); bulk->flags.bypass_document_validation = MONGOC_BYPASS_DOCUMENT_VALIDATION_DEFAULT; bulk->flags.ordered = ordered; bulk->hint = 0; _mongoc_array_init (&bulk->commands, sizeof (mongoc_write_command_t)); return bulk; } mongoc_bulk_operation_t * _mongoc_bulk_operation_new (mongoc_client_t *client, /* IN */ const char *database, /* IN */ const char *collection, /* IN */ mongoc_bulk_write_flags_t flags, /* IN */ const mongoc_write_concern_t *write_concern) /* IN */ { mongoc_bulk_operation_t *bulk; BSON_ASSERT (client); BSON_ASSERT (collection); bulk = mongoc_bulk_operation_new (flags.ordered); bulk->client = client; bulk->database = bson_strdup (database); bulk->collection = bson_strdup (collection); bulk->write_concern = mongoc_write_concern_copy (write_concern); bulk->executed = false; bulk->flags = flags; return bulk; } void mongoc_bulk_operation_destroy (mongoc_bulk_operation_t *bulk) /* IN */ { mongoc_write_command_t *command; int i; if (bulk) { for (i = 0; i < bulk->commands.len; i++) { command = &_mongoc_array_index (&bulk->commands, mongoc_write_command_t, i); _mongoc_write_command_destroy (command); } bson_free (bulk->database); bson_free (bulk->collection); mongoc_write_concern_destroy (bulk->write_concern); _mongoc_array_destroy (&bulk->commands); if (bulk->executed) { _mongoc_write_result_destroy (&bulk->result); } bson_free (bulk); } } void mongoc_bulk_operation_remove (mongoc_bulk_operation_t *bulk, /* IN */ const bson_t *selector) /* IN */ { mongoc_write_command_t command = { 0 }; mongoc_write_command_t *last; ENTRY; BSON_ASSERT (bulk); BSON_ASSERT (selector); if (bulk->commands.len) { last = &_mongoc_array_index (&bulk->commands, mongoc_write_command_t, bulk->commands.len - 1); if ((last->type == MONGOC_WRITE_COMMAND_DELETE) && last->u.delete_.multi) { _mongoc_write_command_delete_append (last, selector); EXIT; } } _mongoc_write_command_init_delete (&command, selector, true, bulk->flags); _mongoc_array_append_val (&bulk->commands, command); EXIT; } void mongoc_bulk_operation_remove_one (mongoc_bulk_operation_t *bulk, /* IN */ const bson_t *selector) /* IN */ { mongoc_write_command_t command = { 0 }; mongoc_write_command_t *last; ENTRY; BSON_ASSERT (bulk); BSON_ASSERT (selector); if (bulk->commands.len) { last = &_mongoc_array_index (&bulk->commands, mongoc_write_command_t, bulk->commands.len - 1); if ((last->type == MONGOC_WRITE_COMMAND_DELETE) && !last->u.delete_.multi) { _mongoc_write_command_delete_append (last, selector); EXIT; } } _mongoc_write_command_init_delete (&command, selector, false, bulk->flags); _mongoc_array_append_val (&bulk->commands, command); EXIT; } void mongoc_bulk_operation_delete (mongoc_bulk_operation_t *bulk, const bson_t *selector) { ENTRY; mongoc_bulk_operation_remove (bulk, selector); EXIT; } void mongoc_bulk_operation_delete_one (mongoc_bulk_operation_t *bulk, const bson_t *selector) { ENTRY; mongoc_bulk_operation_remove_one (bulk, selector); EXIT; } void mongoc_bulk_operation_insert (mongoc_bulk_operation_t *bulk, const bson_t *document) { mongoc_write_command_t command = { 0 }; mongoc_write_command_t *last; ENTRY; BSON_ASSERT (bulk); BSON_ASSERT (document); if (bulk->commands.len) { last = &_mongoc_array_index (&bulk->commands, mongoc_write_command_t, bulk->commands.len - 1); if (last->type == MONGOC_WRITE_COMMAND_INSERT) { _mongoc_write_command_insert_append (last, document); EXIT; } } _mongoc_write_command_init_insert ( &command, document, bulk->flags, !_mongoc_write_concern_needs_gle (bulk->write_concern)); _mongoc_array_append_val (&bulk->commands, command); EXIT; } void mongoc_bulk_operation_replace_one (mongoc_bulk_operation_t *bulk, const bson_t *selector, const bson_t *document, bool upsert) { mongoc_write_command_t command = { 0 }; size_t err_off; mongoc_write_command_t *last; int flags = BSON_VALIDATE_DOT_KEYS|BSON_VALIDATE_DOLLAR_KEYS; BSON_ASSERT (bulk); BSON_ASSERT (selector); BSON_ASSERT (document); ENTRY; if (!bson_validate (document, (bson_validate_flags_t)flags, &err_off)) { MONGOC_WARNING ("%s(): replacement document may not contain " "$ or . in keys. Ignoring document.", BSON_FUNC); EXIT; } if (bulk->commands.len) { last = &_mongoc_array_index (&bulk->commands, mongoc_write_command_t, bulk->commands.len - 1); if (last->type == MONGOC_WRITE_COMMAND_UPDATE) { _mongoc_write_command_update_append (last, selector, document, upsert, false); EXIT; } } _mongoc_write_command_init_update (&command, selector, document, upsert, false, bulk->flags); _mongoc_array_append_val (&bulk->commands, command); EXIT; } void mongoc_bulk_operation_update (mongoc_bulk_operation_t *bulk, const bson_t *selector, const bson_t *document, bool upsert) { bool multi = true; mongoc_write_command_t command = { 0 }; bson_iter_t iter; mongoc_write_command_t *last; BSON_ASSERT (bulk); BSON_ASSERT (selector); BSON_ASSERT (document); ENTRY; if (bson_iter_init (&iter, document)) { while (bson_iter_next (&iter)) { if (!strchr (bson_iter_key (&iter), '$')) { MONGOC_WARNING ("%s(): update only works with $ operators.", BSON_FUNC); EXIT; } } } if (bulk->commands.len) { last = &_mongoc_array_index (&bulk->commands, mongoc_write_command_t, bulk->commands.len - 1); if (last->type == MONGOC_WRITE_COMMAND_UPDATE) { _mongoc_write_command_update_append (last, selector, document, upsert, multi); EXIT; } } _mongoc_write_command_init_update (&command, selector, document, upsert, multi, bulk->flags); _mongoc_array_append_val (&bulk->commands, command); EXIT; } void mongoc_bulk_operation_update_one (mongoc_bulk_operation_t *bulk, const bson_t *selector, const bson_t *document, bool upsert) { mongoc_write_command_t command = { 0 }; bson_iter_t iter; mongoc_write_command_t *last; BSON_ASSERT (bulk); BSON_ASSERT (selector); BSON_ASSERT (document); ENTRY; if (bson_iter_init (&iter, document)) { while (bson_iter_next (&iter)) { if (!strchr (bson_iter_key (&iter), '$')) { MONGOC_WARNING ("%s(): update_one only works with $ operators.", BSON_FUNC); EXIT; } } } if (bulk->commands.len) { last = &_mongoc_array_index (&bulk->commands, mongoc_write_command_t, bulk->commands.len - 1); if (last->type == MONGOC_WRITE_COMMAND_UPDATE) { _mongoc_write_command_update_append (last, selector, document, upsert, false); EXIT; } } _mongoc_write_command_init_update (&command, selector, document, upsert, false, bulk->flags); _mongoc_array_append_val (&bulk->commands, command); EXIT; } uint32_t mongoc_bulk_operation_execute (mongoc_bulk_operation_t *bulk, /* IN */ bson_t *reply, /* OUT */ bson_error_t *error) /* OUT */ { mongoc_cluster_t *cluster; mongoc_write_command_t *command; mongoc_server_stream_t *server_stream; bool ret; uint32_t offset = 0; int i; ENTRY; BSON_ASSERT (bulk); cluster = &bulk->client->cluster; if (bulk->executed) { _mongoc_write_result_destroy (&bulk->result); } _mongoc_write_result_init (&bulk->result); bulk->executed = true; if (!bulk->client) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "mongoc_bulk_operation_execute() requires a client " "and one has not been set."); RETURN (false); } else if (!bulk->database) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "mongoc_bulk_operation_execute() requires a database " "and one has not been set."); RETURN (false); } else if (!bulk->collection) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "mongoc_bulk_operation_execute() requires a collection " "and one has not been set."); RETURN (false); } if (reply) { bson_init (reply); } if (!bulk->commands.len) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "Cannot do an empty bulk write"); RETURN (false); } if (bulk->hint) { server_stream = mongoc_cluster_stream_for_server (cluster, bulk->hint, true /* reconnect_ok */, error); } else { server_stream = mongoc_cluster_stream_for_writes (cluster, error); } if (!server_stream) { RETURN (false); } for (i = 0; i < bulk->commands.len; i++) { command = &_mongoc_array_index (&bulk->commands, mongoc_write_command_t, i); _mongoc_write_command_execute (command, bulk->client, server_stream, bulk->database, bulk->collection, bulk->write_concern, offset, &bulk->result); bulk->hint = command->hint; if (bulk->result.failed && bulk->flags.ordered) { GOTO (cleanup); } offset += command->n_documents; } cleanup: ret = _mongoc_write_result_complete (&bulk->result, reply, error); mongoc_server_stream_cleanup (server_stream); RETURN (ret ? bulk->hint : 0); } void mongoc_bulk_operation_set_write_concern (mongoc_bulk_operation_t *bulk, const mongoc_write_concern_t *write_concern) { BSON_ASSERT (bulk); if (bulk->write_concern) { mongoc_write_concern_destroy (bulk->write_concern); } if (write_concern) { bulk->write_concern = mongoc_write_concern_copy (write_concern); } else { bulk->write_concern = mongoc_write_concern_new (); } } const mongoc_write_concern_t * mongoc_bulk_operation_get_write_concern (const mongoc_bulk_operation_t *bulk) { BSON_ASSERT (bulk); return bulk->write_concern; } void mongoc_bulk_operation_set_database (mongoc_bulk_operation_t *bulk, const char *database) { BSON_ASSERT (bulk); if (bulk->database) { bson_free (bulk->database); } bulk->database = bson_strdup (database); } void mongoc_bulk_operation_set_collection (mongoc_bulk_operation_t *bulk, const char *collection) { BSON_ASSERT (bulk); if (bulk->collection) { bson_free (bulk->collection); } bulk->collection = bson_strdup (collection); } void mongoc_bulk_operation_set_client (mongoc_bulk_operation_t *bulk, void *client) { BSON_ASSERT (bulk); bulk->client = (mongoc_client_t *)client; } void mongoc_bulk_operation_set_hint (mongoc_bulk_operation_t *bulk, uint32_t hint) { BSON_ASSERT (bulk); bulk->hint = hint; } void mongoc_bulk_operation_set_bypass_document_validation (mongoc_bulk_operation_t *bulk, bool bypass) { BSON_ASSERT (bulk); bulk->flags.bypass_document_validation = bypass ? MONGOC_BYPASS_DOCUMENT_VALIDATION_TRUE : MONGOC_BYPASS_DOCUMENT_VALIDATION_FALSE; } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-bulk-operation.h0000664000175000017500000001142712673034026024210 0ustar jmikolajmikola/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_BULK_OPERATION_H #define MONGOC_BULK_OPERATION_H #include #include "mongoc-write-concern.h" #define MONGOC_BULK_WRITE_FLAGS_INIT { true, MONGOC_BYPASS_DOCUMENT_VALIDATION_DEFAULT } BSON_BEGIN_DECLS typedef struct _mongoc_bulk_operation_t mongoc_bulk_operation_t; typedef struct _mongoc_bulk_write_flags_t mongoc_bulk_write_flags_t; void mongoc_bulk_operation_destroy (mongoc_bulk_operation_t *bulk); uint32_t mongoc_bulk_operation_execute (mongoc_bulk_operation_t *bulk, bson_t *reply, bson_error_t *error); void mongoc_bulk_operation_delete (mongoc_bulk_operation_t *bulk, const bson_t *selector) BSON_GNUC_DEPRECATED_FOR (mongoc_bulk_operation_remove); void mongoc_bulk_operation_delete_one (mongoc_bulk_operation_t *bulk, const bson_t *selector) BSON_GNUC_DEPRECATED_FOR (mongoc_bulk_operation_remove_one); void mongoc_bulk_operation_insert (mongoc_bulk_operation_t *bulk, const bson_t *document); void mongoc_bulk_operation_remove (mongoc_bulk_operation_t *bulk, const bson_t *selector); void mongoc_bulk_operation_remove_one (mongoc_bulk_operation_t *bulk, const bson_t *selector); void mongoc_bulk_operation_replace_one (mongoc_bulk_operation_t *bulk, const bson_t *selector, const bson_t *document, bool upsert); void mongoc_bulk_operation_update (mongoc_bulk_operation_t *bulk, const bson_t *selector, const bson_t *document, bool upsert); void mongoc_bulk_operation_update_one (mongoc_bulk_operation_t *bulk, const bson_t *selector, const bson_t *document, bool upsert); void mongoc_bulk_operation_set_bypass_document_validation (mongoc_bulk_operation_t *bulk, bool bypass); /* * The following functions are really only useful by language bindings and * those wanting to replay a bulk operation to a number of clients or * collections. */ mongoc_bulk_operation_t *mongoc_bulk_operation_new (bool ordered); void mongoc_bulk_operation_set_write_concern (mongoc_bulk_operation_t *bulk, const mongoc_write_concern_t *write_concern); void mongoc_bulk_operation_set_database (mongoc_bulk_operation_t *bulk, const char *database); void mongoc_bulk_operation_set_collection (mongoc_bulk_operation_t *bulk, const char *collection); void mongoc_bulk_operation_set_client (mongoc_bulk_operation_t *bulk, void *client); void mongoc_bulk_operation_set_hint (mongoc_bulk_operation_t *bulk, uint32_t hint); const mongoc_write_concern_t *mongoc_bulk_operation_get_write_concern (const mongoc_bulk_operation_t *bulk); BSON_END_DECLS #endif /* MONGOC_BULK_OPERATION_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-client-pool-private.h0000664000175000017500000000174712673034026025156 0ustar jmikolajmikola/* * Copyright 2015 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_CLIENT_POOL_PRIVATE_H #define MONGOC_CLIENT_POOL_PRIVATE_H #if !defined (MONGOC_I_AM_A_DRIVER) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #include #include "mongoc-client-pool.h" BSON_BEGIN_DECLS size_t mongoc_client_pool_get_size(mongoc_client_pool_t *pool); BSON_END_DECLS #endif /* MONGOC_CLIENT_POOL_PRIVATE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-client-pool.c0000664000175000017500000001430412673034026023472 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "mongoc-counters-private.h" #include "mongoc-client-pool-private.h" #include "mongoc-client-pool.h" #include "mongoc-client-private.h" #include "mongoc-queue-private.h" #include "mongoc-thread-private.h" #include "mongoc-topology-private.h" #include "mongoc-trace.h" struct _mongoc_client_pool_t { mongoc_mutex_t mutex; mongoc_cond_t cond; mongoc_queue_t queue; mongoc_topology_t *topology; mongoc_uri_t *uri; uint32_t min_pool_size; uint32_t max_pool_size; uint32_t size; #ifdef MONGOC_ENABLE_SSL bool ssl_opts_set; mongoc_ssl_opt_t ssl_opts; #endif }; #ifdef MONGOC_ENABLE_SSL void mongoc_client_pool_set_ssl_opts (mongoc_client_pool_t *pool, const mongoc_ssl_opt_t *opts) { BSON_ASSERT (pool); mongoc_mutex_lock (&pool->mutex); memset (&pool->ssl_opts, 0, sizeof pool->ssl_opts); pool->ssl_opts_set = false; if (opts) { memcpy (&pool->ssl_opts, opts, sizeof pool->ssl_opts); pool->ssl_opts_set = true; } mongoc_topology_scanner_set_ssl_opts (pool->topology->scanner, &pool->ssl_opts); mongoc_mutex_unlock (&pool->mutex); } #endif mongoc_client_pool_t * mongoc_client_pool_new (const mongoc_uri_t *uri) { mongoc_topology_t *topology; mongoc_client_pool_t *pool; const bson_t *b; bson_iter_t iter; ENTRY; BSON_ASSERT (uri); #ifndef MONGOC_ENABLE_SSL if (mongoc_uri_get_ssl (uri)) { MONGOC_ERROR ("Can't create SSL client pool," " SSL not enabled in this build."); return NULL; } #endif pool = (mongoc_client_pool_t *)bson_malloc0(sizeof *pool); mongoc_mutex_init(&pool->mutex); _mongoc_queue_init(&pool->queue); pool->uri = mongoc_uri_copy(uri); pool->min_pool_size = 0; pool->max_pool_size = 100; pool->size = 0; topology = mongoc_topology_new(uri, false); pool->topology = topology; b = mongoc_uri_get_options(pool->uri); if (bson_iter_init_find_case(&iter, b, "minpoolsize")) { if (BSON_ITER_HOLDS_INT32(&iter)) { pool->min_pool_size = BSON_MAX(0, bson_iter_int32(&iter)); } } if (bson_iter_init_find_case(&iter, b, "maxpoolsize")) { if (BSON_ITER_HOLDS_INT32(&iter)) { pool->max_pool_size = BSON_MAX(1, bson_iter_int32(&iter)); } } mongoc_counter_client_pools_active_inc(); RETURN(pool); } void mongoc_client_pool_destroy (mongoc_client_pool_t *pool) { mongoc_client_t *client; ENTRY; BSON_ASSERT (pool); while ((client = (mongoc_client_t *)_mongoc_queue_pop_head(&pool->queue))) { mongoc_client_destroy(client); } mongoc_topology_destroy (pool->topology); mongoc_uri_destroy(pool->uri); mongoc_mutex_destroy(&pool->mutex); mongoc_cond_destroy(&pool->cond); bson_free(pool); mongoc_counter_client_pools_active_dec(); mongoc_counter_client_pools_disposed_inc(); EXIT; } mongoc_client_t * mongoc_client_pool_pop (mongoc_client_pool_t *pool) { mongoc_client_t *client; ENTRY; BSON_ASSERT (pool); mongoc_mutex_lock(&pool->mutex); again: if (!(client = (mongoc_client_t *)_mongoc_queue_pop_head(&pool->queue))) { if (pool->size < pool->max_pool_size) { client = _mongoc_client_new_from_uri(pool->uri, pool->topology); #ifdef MONGOC_ENABLE_SSL if (pool->ssl_opts_set) { mongoc_client_set_ssl_opts (client, &pool->ssl_opts); } #endif pool->size++; } else { mongoc_cond_wait(&pool->cond, &pool->mutex); GOTO(again); } } mongoc_mutex_unlock(&pool->mutex); RETURN(client); } mongoc_client_t * mongoc_client_pool_try_pop (mongoc_client_pool_t *pool) { mongoc_client_t *client; ENTRY; BSON_ASSERT (pool); mongoc_mutex_lock(&pool->mutex); if (!(client = (mongoc_client_t *)_mongoc_queue_pop_head(&pool->queue))) { if (pool->size < pool->max_pool_size) { client = _mongoc_client_new_from_uri(pool->uri, pool->topology); #ifdef MONGOC_ENABLE_SSL if (pool->ssl_opts_set) { mongoc_client_set_ssl_opts (client, &pool->ssl_opts); } #endif pool->size++; } } mongoc_mutex_unlock(&pool->mutex); RETURN(client); } void mongoc_client_pool_push (mongoc_client_pool_t *pool, mongoc_client_t *client) { ENTRY; BSON_ASSERT (pool); BSON_ASSERT (client); mongoc_mutex_lock(&pool->mutex); if (pool->size > pool->min_pool_size) { mongoc_client_t *old_client; old_client = (mongoc_client_t *)_mongoc_queue_pop_head (&pool->queue); if (old_client) { mongoc_client_destroy (old_client); pool->size--; } } mongoc_mutex_unlock(&pool->mutex); mongoc_mutex_lock (&pool->mutex); _mongoc_queue_push_tail (&pool->queue, client); mongoc_cond_signal(&pool->cond); mongoc_mutex_unlock(&pool->mutex); EXIT; } size_t mongoc_client_pool_get_size (mongoc_client_pool_t *pool) { size_t size = 0; ENTRY; mongoc_mutex_lock (&pool->mutex); size = pool->size; mongoc_mutex_unlock (&pool->mutex); RETURN (size); } void mongoc_client_pool_max_size(mongoc_client_pool_t *pool, uint32_t max_pool_size) { ENTRY; mongoc_mutex_lock (&pool->mutex); pool->max_pool_size = max_pool_size; mongoc_mutex_unlock (&pool->mutex); EXIT; } void mongoc_client_pool_min_size(mongoc_client_pool_t *pool, uint32_t min_pool_size) { ENTRY; mongoc_mutex_lock (&pool->mutex); pool->min_pool_size = min_pool_size; mongoc_mutex_unlock (&pool->mutex); EXIT; } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-client-pool.h0000664000175000017500000000403312673034026023475 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_CLIENT_POOL_H #define MONGOC_CLIENT_POOL_H #if !defined (MONGOC_INSIDE) && !defined (MONGOC_COMPILATION) # error "Only can be included directly." #endif #include #include "mongoc-client.h" #include "mongoc-config.h" #ifdef MONGOC_ENABLE_SSL # include "mongoc-ssl.h" #endif #include "mongoc-uri.h" BSON_BEGIN_DECLS typedef struct _mongoc_client_pool_t mongoc_client_pool_t; mongoc_client_pool_t *mongoc_client_pool_new (const mongoc_uri_t *uri); void mongoc_client_pool_destroy (mongoc_client_pool_t *pool); mongoc_client_t *mongoc_client_pool_pop (mongoc_client_pool_t *pool); void mongoc_client_pool_push (mongoc_client_pool_t *pool, mongoc_client_t *client); mongoc_client_t *mongoc_client_pool_try_pop (mongoc_client_pool_t *pool); void mongoc_client_pool_max_size(mongoc_client_pool_t *pool, uint32_t max_pool_size); void mongoc_client_pool_min_size(mongoc_client_pool_t *pool, uint32_t min_pool_size); #ifdef MONGOC_ENABLE_SSL void mongoc_client_pool_set_ssl_opts (mongoc_client_pool_t *pool, const mongoc_ssl_opt_t *opts); #endif BSON_END_DECLS #endif /* MONGOC_CLIENT_POOL_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-client-private.h0000664000175000017500000001066412673034026024205 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_CLIENT_PRIVATE_H #define MONGOC_CLIENT_PRIVATE_H #if !defined (MONGOC_I_AM_A_DRIVER) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #include #include "mongoc-buffer-private.h" #include "mongoc-client.h" #include "mongoc-cluster-private.h" #include "mongoc-config.h" #include "mongoc-host-list.h" #include "mongoc-read-prefs.h" #include "mongoc-rpc-private.h" #include "mongoc-opcode.h" #ifdef MONGOC_ENABLE_SSL #include "mongoc-ssl.h" #endif #include "mongoc-stream.h" #include "mongoc-topology-private.h" #include "mongoc-write-concern.h" BSON_BEGIN_DECLS /* protocol versions this driver can speak */ #define WIRE_VERSION_MIN 0 #define WIRE_VERSION_MAX 4 /* first version that supported aggregation cursors */ #define WIRE_VERSION_AGG_CURSOR 1 /* first version that supported "insert", "update", "delete" commands */ #define WIRE_VERSION_WRITE_CMD 2 /* first version when SCRAM-SHA-1 replaced MONGODB-CR as default auth mech */ #define WIRE_VERSION_SCRAM_DEFAULT 3 /* first version that supported "find" and "getMore" commands */ #define WIRE_VERSION_FIND_CMD 4 /* first version with "killCursors" command */ #define WIRE_VERSION_KILLCURSORS_CMD 4 /* first version when findAndModify accepts writeConcern */ #define WIRE_VERSION_FAM_WRITE_CONCERN 4 /* first version to support readConcern */ #define WIRE_VERSION_READ_CONCERN 4 struct _mongoc_client_t { uint32_t request_id; mongoc_list_t *conns; mongoc_uri_t *uri; mongoc_cluster_t cluster; bool in_exhaust; mongoc_stream_initiator_t initiator; void *initiator_data; #ifdef MONGOC_ENABLE_SSL bool use_ssl; mongoc_ssl_opt_t ssl_opts; char *pem_subject; #endif mongoc_topology_t *topology; mongoc_read_prefs_t *read_prefs; mongoc_read_concern_t *read_concern; mongoc_write_concern_t *write_concern; }; mongoc_client_t * _mongoc_client_new_from_uri (const mongoc_uri_t *uri, mongoc_topology_t *topology); mongoc_stream_t * mongoc_client_default_stream_initiator (const mongoc_uri_t *uri, const mongoc_host_list_t *host, void *user_data, bson_error_t *error); mongoc_stream_t * _mongoc_client_create_stream (mongoc_client_t *client, const mongoc_host_list_t *host, bson_error_t *error); bool _mongoc_client_recv (mongoc_client_t *client, mongoc_rpc_t *rpc, mongoc_buffer_t *buffer, mongoc_server_stream_t *server_stream, bson_error_t *error); bool _mongoc_client_recv_gle (mongoc_client_t *client, mongoc_server_stream_t *server_stream, bson_t **gle_doc, bson_error_t *error); void _mongoc_topology_background_thread_start (mongoc_topology_t *topology); void _mongoc_topology_background_thread_stop (mongoc_topology_t *topology); mongoc_server_description_t * _mongoc_client_get_server_description (mongoc_client_t *client, uint32_t server_id); void _mongoc_client_kill_cursor (mongoc_client_t *client, uint32_t server_id, int64_t cursor_id, const char *db, const char *collection); BSON_END_DECLS #endif /* MONGOC_CLIENT_PRIVATE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-client.c0000664000175000017500000012226212673034026022526 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #ifndef _WIN32 # include # include #endif #include "mongoc-cursor-array-private.h" #include "mongoc-client-private.h" #include "mongoc-collection-private.h" #include "mongoc-config.h" #include "mongoc-counters-private.h" #include "mongoc-database-private.h" #include "mongoc-gridfs-private.h" #include "mongoc-error.h" #include "mongoc-log.h" #include "mongoc-queue-private.h" #include "mongoc-socket.h" #include "mongoc-stream-buffered.h" #include "mongoc-stream-socket.h" #include "mongoc-thread-private.h" #include "mongoc-trace.h" #include "mongoc-uri-private.h" #include "mongoc-util-private.h" #ifdef MONGOC_ENABLE_SSL #include "mongoc-stream-tls.h" #include "mongoc-ssl-private.h" #endif #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "client" static void _mongoc_client_op_killcursors (mongoc_cluster_t *cluster, mongoc_server_stream_t *server_stream, int64_t cursor_id); static void _mongoc_client_killcursors_command (mongoc_cluster_t *cluster, mongoc_server_stream_t *server_stream, int64_t cursor_id, const char *db, const char *collection); /* *-------------------------------------------------------------------------- * * mongoc_client_connect_tcp -- * * Connect to a host using a TCP socket. * * This will be performed synchronously and return a mongoc_stream_t * that can be used to connect with the remote host. * * Returns: * A newly allocated mongoc_stream_t if successful; otherwise * NULL and @error is set. * * Side effects: * @error is set if return value is NULL. * *-------------------------------------------------------------------------- */ static mongoc_stream_t * mongoc_client_connect_tcp (const mongoc_uri_t *uri, const mongoc_host_list_t *host, bson_error_t *error) { mongoc_socket_t *sock = NULL; struct addrinfo hints; struct addrinfo *result, *rp; int32_t connecttimeoutms; int64_t expire_at; char portstr [8]; int s; ENTRY; BSON_ASSERT (uri); BSON_ASSERT (host); connecttimeoutms = mongoc_uri_get_option_as_int32 ( uri, "connecttimeoutms", MONGOC_DEFAULT_CONNECTTIMEOUTMS); BSON_ASSERT (connecttimeoutms); expire_at = bson_get_monotonic_time () + (connecttimeoutms * 1000L); bson_snprintf (portstr, sizeof portstr, "%hu", host->port); memset (&hints, 0, sizeof hints); hints.ai_family = host->family; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = 0; hints.ai_protocol = 0; s = getaddrinfo (host->host, portstr, &hints, &result); if (s != 0) { mongoc_counter_dns_failure_inc (); bson_set_error(error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_NAME_RESOLUTION, "Failed to resolve %s", host->host); RETURN (NULL); } mongoc_counter_dns_success_inc (); for (rp = result; rp; rp = rp->ai_next) { /* * Create a new non-blocking socket. */ if (!(sock = mongoc_socket_new (rp->ai_family, rp->ai_socktype, rp->ai_protocol))) { continue; } /* * Try to connect to the peer. */ if (0 != mongoc_socket_connect (sock, rp->ai_addr, (socklen_t)rp->ai_addrlen, expire_at)) { char *errmsg; char errmsg_buf[BSON_ERROR_BUFFER_SIZE]; char ip[255]; mongoc_socket_inet_ntop (rp, ip, sizeof ip); errmsg = bson_strerror_r ( mongoc_socket_errno (sock), errmsg_buf, sizeof errmsg_buf); MONGOC_WARNING ("Failed to connect to: %s:%d, error: %d, %s\n", ip, host->port, mongoc_socket_errno(sock), errmsg); mongoc_socket_destroy (sock); sock = NULL; continue; } break; } if (!sock) { bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_CONNECT, "Failed to connect to target host: %s", host->host_and_port); freeaddrinfo (result); RETURN (NULL); } freeaddrinfo (result); return mongoc_stream_socket_new (sock); } /* *-------------------------------------------------------------------------- * * mongoc_client_connect_unix -- * * Connect to a MongoDB server using a UNIX domain socket. * * Returns: * A newly allocated mongoc_stream_t if successful; otherwise * NULL and @error is set. * * Side effects: * @error is set if return value is NULL. * *-------------------------------------------------------------------------- */ static mongoc_stream_t * mongoc_client_connect_unix (const mongoc_uri_t *uri, const mongoc_host_list_t *host, bson_error_t *error) { #ifdef _WIN32 ENTRY; bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_CONNECT, "UNIX domain sockets not supported on win32."); RETURN (NULL); #else struct sockaddr_un saddr; mongoc_socket_t *sock; mongoc_stream_t *ret = NULL; ENTRY; BSON_ASSERT (uri); BSON_ASSERT (host); memset (&saddr, 0, sizeof saddr); saddr.sun_family = AF_UNIX; bson_snprintf (saddr.sun_path, sizeof saddr.sun_path - 1, "%s", host->host); sock = mongoc_socket_new (AF_UNIX, SOCK_STREAM, 0); if (sock == NULL) { bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, "Failed to create socket."); RETURN (NULL); } if (-1 == mongoc_socket_connect (sock, (struct sockaddr *)&saddr, sizeof saddr, -1)) { mongoc_socket_destroy (sock); bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_CONNECT, "Failed to connect to UNIX domain socket."); RETURN (NULL); } ret = mongoc_stream_socket_new (sock); RETURN (ret); #endif } /* *-------------------------------------------------------------------------- * * mongoc_client_default_stream_initiator -- * * A mongoc_stream_initiator_t that will handle the various type * of supported sockets by MongoDB including TCP and UNIX. * * Language binding authors may want to implement an alternate * version of this method to use their native stream format. * * Returns: * A mongoc_stream_t if successful; otherwise NULL and @error is set. * * Side effects: * @error is set if return value is NULL. * *-------------------------------------------------------------------------- */ mongoc_stream_t * mongoc_client_default_stream_initiator (const mongoc_uri_t *uri, const mongoc_host_list_t *host, void *user_data, bson_error_t *error) { mongoc_stream_t *base_stream = NULL; #ifdef MONGOC_ENABLE_SSL mongoc_client_t *client = (mongoc_client_t *)user_data; const char *mechanism; int32_t connecttimeoutms; #endif BSON_ASSERT (uri); BSON_ASSERT (host); #ifndef MONGOC_ENABLE_SSL if (mongoc_uri_get_ssl (uri)) { bson_set_error (error, MONGOC_ERROR_CLIENT, MONGOC_ERROR_CLIENT_NO_ACCEPTABLE_PEER, "SSL is not enabled in this build of mongo-c-driver."); return NULL; } #endif switch (host->family) { #if defined(AF_INET6) case AF_INET6: #endif case AF_INET: base_stream = mongoc_client_connect_tcp (uri, host, error); break; case AF_UNIX: base_stream = mongoc_client_connect_unix (uri, host, error); break; default: bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_INVALID_TYPE, "Invalid address family: 0x%02x", host->family); break; } #ifdef MONGOC_ENABLE_SSL if (base_stream) { mechanism = mongoc_uri_get_auth_mechanism (uri); if (client->use_ssl || (mechanism && (0 == strcmp (mechanism, "MONGODB-X509")))) { base_stream = mongoc_stream_tls_new (base_stream, &client->ssl_opts, true); if (!base_stream) { bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, "Failed initialize TLS state."); return NULL; } connecttimeoutms = mongoc_uri_get_option_as_int32 ( uri, "connecttimeoutms", MONGOC_DEFAULT_CONNECTTIMEOUTMS); if (!mongoc_stream_tls_do_handshake (base_stream, connecttimeoutms) || !mongoc_stream_tls_check_cert (base_stream, host->host)) { bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, "Failed to handshake and validate TLS certificate."); mongoc_stream_destroy (base_stream); return NULL; } } } #endif return base_stream ? mongoc_stream_buffered_new (base_stream, 1024) : NULL; } /* *-------------------------------------------------------------------------- * * _mongoc_client_create_stream -- * * INTERNAL API * * This function is used by the mongoc_cluster_t to initiate a * new stream. This is done because cluster is private API and * those using mongoc_client_t may need to override this process. * * This function calls the default initiator for new streams. * * Returns: * A newly allocated mongoc_stream_t if successful; otherwise * NULL and @error is set. * * Side effects: * @error is set if return value is NULL. * *-------------------------------------------------------------------------- */ mongoc_stream_t * _mongoc_client_create_stream (mongoc_client_t *client, const mongoc_host_list_t *host, bson_error_t *error) { BSON_ASSERT (client); BSON_ASSERT (host); return client->initiator (client->uri, host, client->initiator_data, error); } /* *-------------------------------------------------------------------------- * * _mongoc_client_recv -- * * Receives a RPC from a remote MongoDB cluster node. * * Returns: * true if successful; otherwise false and @error is set. * * Side effects: * @error is set if return value is false. * *-------------------------------------------------------------------------- */ bool _mongoc_client_recv (mongoc_client_t *client, mongoc_rpc_t *rpc, mongoc_buffer_t *buffer, mongoc_server_stream_t *server_stream, bson_error_t *error) { BSON_ASSERT (client); BSON_ASSERT (rpc); BSON_ASSERT (buffer); BSON_ASSERT (server_stream); if (!mongoc_cluster_try_recv (&client->cluster, rpc, buffer, server_stream, error)) { mongoc_topology_invalidate_server (client->topology, server_stream->sd->id); return false; } return true; } /* *-------------------------------------------------------------------------- * * _bson_to_error -- * * A helper routine to convert a bson document to a bson_error_t. * * Returns: * None. * * Side effects: * @error is set if non-null. * *-------------------------------------------------------------------------- */ static void _bson_to_error (const bson_t *b, bson_error_t *error) { bson_iter_t iter; int code = 0; BSON_ASSERT (b); if (!error) { return; } if (bson_iter_init_find(&iter, b, "code") && BSON_ITER_HOLDS_INT32(&iter)) { code = bson_iter_int32(&iter); } if (bson_iter_init_find(&iter, b, "$err") && BSON_ITER_HOLDS_UTF8(&iter)) { bson_set_error(error, MONGOC_ERROR_QUERY, code, "%s", bson_iter_utf8(&iter, NULL)); return; } if (bson_iter_init_find(&iter, b, "errmsg") && BSON_ITER_HOLDS_UTF8(&iter)) { bson_set_error(error, MONGOC_ERROR_QUERY, code, "%s", bson_iter_utf8(&iter, NULL)); return; } bson_set_error(error, MONGOC_ERROR_QUERY, MONGOC_ERROR_QUERY_FAILURE, "An unknown error ocurred on the server."); } /* *-------------------------------------------------------------------------- * * mongoc_client_recv_gle -- * * INTERNAL API * * This function is used to receive the next RPC from a cluster * node, expecting it to be the response to a getlasterror command. * * The RPC is parsed into @error if it is an error and false is * returned. * * If the operation was successful, true is returned. * * if @gle_doc is not NULL, then the actual response document for * the gle command will be stored as an out parameter. The caller * is responsible for freeing it in this case. * * Returns: * true if getlasterror was success; otherwise false. * * Side effects: * @gle_doc will be set if non NULL and a reply was received. * @error if return value is false, and @gle_doc is set to NULL. * *-------------------------------------------------------------------------- */ bool _mongoc_client_recv_gle (mongoc_client_t *client, mongoc_server_stream_t *server_stream, bson_t **gle_doc, bson_error_t *error) { mongoc_buffer_t buffer; mongoc_rpc_t rpc; bson_iter_t iter; bool ret = false; bson_t b; ENTRY; BSON_ASSERT (client); BSON_ASSERT (server_stream); if (gle_doc) { *gle_doc = NULL; } _mongoc_buffer_init (&buffer, NULL, 0, NULL, NULL); if (!mongoc_cluster_try_recv (&client->cluster, &rpc, &buffer, server_stream, error)) { mongoc_topology_invalidate_server (client->topology, server_stream->sd->id); GOTO (cleanup); } if (rpc.header.opcode != MONGOC_OPCODE_REPLY) { bson_set_error (error, MONGOC_ERROR_PROTOCOL, MONGOC_ERROR_PROTOCOL_INVALID_REPLY, "Received message other than OP_REPLY."); GOTO (cleanup); } if (_mongoc_rpc_reply_get_first (&rpc.reply, &b)) { if ((rpc.reply.flags & MONGOC_REPLY_QUERY_FAILURE)) { _bson_to_error (&b, error); bson_destroy (&b); GOTO (cleanup); } if (gle_doc) { *gle_doc = bson_copy (&b); } if (!bson_iter_init_find (&iter, &b, "ok") || BSON_ITER_HOLDS_DOUBLE (&iter)) { if (bson_iter_double (&iter) == 0.0) { _bson_to_error (&b, error); } } bson_destroy (&b); ret = true; } cleanup: _mongoc_buffer_destroy (&buffer); RETURN (ret); } /* *-------------------------------------------------------------------------- * * mongoc_client_new -- * * Create a new mongoc_client_t using the URI provided. * * @uri should be a MongoDB URI string such as "mongodb://localhost/" * More information on the format can be found at * http://docs.mongodb.org/manual/reference/connection-string/ * * Returns: * A newly allocated mongoc_client_t or NULL if @uri_string is * invalid. * * Side effects: * None. * *-------------------------------------------------------------------------- */ mongoc_client_t * mongoc_client_new(const char *uri_string) { mongoc_topology_t *topology; mongoc_client_t *client; mongoc_uri_t *uri; if (!uri_string) { uri_string = "mongodb://127.0.0.1/"; } if (!(uri = mongoc_uri_new (uri_string))) { return NULL; } topology = mongoc_topology_new(uri, true); client = _mongoc_client_new_from_uri (uri, topology); mongoc_uri_destroy (uri); return client; } /* *-------------------------------------------------------------------------- * * mongoc_client_set_ssl_opts * * set ssl opts for a client * * Returns: * Nothing * * Side effects: * None. * *-------------------------------------------------------------------------- */ #ifdef MONGOC_ENABLE_SSL void mongoc_client_set_ssl_opts (mongoc_client_t *client, const mongoc_ssl_opt_t *opts) { BSON_ASSERT (client); BSON_ASSERT (opts); client->use_ssl = true; memcpy (&client->ssl_opts, opts, sizeof client->ssl_opts); bson_free (client->pem_subject); client->pem_subject = NULL; if (opts->pem_file) { client->pem_subject = _mongoc_ssl_extract_subject (opts->pem_file); } if (client->topology->single_threaded) { mongoc_topology_scanner_set_ssl_opts (client->topology->scanner, &client->ssl_opts); } } #endif /* *-------------------------------------------------------------------------- * * mongoc_client_new_from_uri -- * * Create a new mongoc_client_t for a mongoc_uri_t. * * Returns: * A newly allocated mongoc_client_t. * * Side effects: * None. * *-------------------------------------------------------------------------- */ mongoc_client_t * mongoc_client_new_from_uri (const mongoc_uri_t *uri) { mongoc_topology_t *topology; topology = mongoc_topology_new (uri, true); return _mongoc_client_new_from_uri (uri, topology); } /* *-------------------------------------------------------------------------- * * _mongoc_client_new_from_uri -- * * Create a new mongoc_client_t for a mongoc_uri_t and a given * topology object. * * Returns: * A newly allocated mongoc_client_t. * * Side effects: * None. * *-------------------------------------------------------------------------- */ mongoc_client_t * _mongoc_client_new_from_uri (const mongoc_uri_t *uri, mongoc_topology_t *topology) { mongoc_client_t *client; const mongoc_read_prefs_t *read_prefs; const mongoc_read_concern_t *read_concern; const mongoc_write_concern_t *write_concern; BSON_ASSERT (uri); #ifndef MONGOC_ENABLE_SSL if (mongoc_uri_get_ssl (uri)) { MONGOC_ERROR ("Can't create SSL client, SSL not enabled in this build."); return NULL; } #endif client = (mongoc_client_t *)bson_malloc0(sizeof *client); client->uri = mongoc_uri_copy (uri); client->request_id = rand (); client->initiator = mongoc_client_default_stream_initiator; client->initiator_data = client; client->topology = topology; write_concern = mongoc_uri_get_write_concern (client->uri); client->write_concern = mongoc_write_concern_copy (write_concern); read_concern = mongoc_uri_get_read_concern (client->uri); client->read_concern = mongoc_read_concern_copy (read_concern); read_prefs = mongoc_uri_get_read_prefs_t (client->uri); client->read_prefs = mongoc_read_prefs_copy (read_prefs); mongoc_cluster_init (&client->cluster, client->uri, client); #ifdef MONGOC_ENABLE_SSL client->use_ssl = false; if (mongoc_uri_get_ssl (client->uri)) { /* sets use_ssl = true */ mongoc_client_set_ssl_opts (client, mongoc_ssl_opt_get_default ()); } #endif mongoc_counter_clients_active_inc (); return client; } /* *-------------------------------------------------------------------------- * * mongoc_client_destroy -- * * Destroys a mongoc_client_t and cleans up all resources associated * with the client instance. * * Returns: * None. * * Side effects: * @client is destroyed. * *-------------------------------------------------------------------------- */ void mongoc_client_destroy (mongoc_client_t *client) { if (client) { #ifdef MONGOC_ENABLE_SSL bson_free (client->pem_subject); #endif if (client->topology->single_threaded) { mongoc_topology_destroy(client->topology); } mongoc_write_concern_destroy (client->write_concern); mongoc_read_concern_destroy (client->read_concern); mongoc_read_prefs_destroy (client->read_prefs); mongoc_cluster_destroy (&client->cluster); mongoc_uri_destroy (client->uri); bson_free (client); mongoc_counter_clients_active_dec (); mongoc_counter_clients_disposed_inc (); } } /* *-------------------------------------------------------------------------- * * mongoc_client_get_uri -- * * Fetch the URI used for @client. * * Returns: * A mongoc_uri_t that should not be modified or freed. * * Side effects: * None. * *-------------------------------------------------------------------------- */ const mongoc_uri_t * mongoc_client_get_uri (const mongoc_client_t *client) { BSON_ASSERT (client); return client->uri; } /* *-------------------------------------------------------------------------- * * mongoc_client_get_database -- * * Fetches a newly allocated database structure to communicate with * a database over @client. * * @database should be a db name such as "test". * * This structure should be freed when the caller is done with it * using mongoc_database_destroy(). * * Returns: * A newly allocated mongoc_database_t. * * Side effects: * None. * *-------------------------------------------------------------------------- */ mongoc_database_t * mongoc_client_get_database (mongoc_client_t *client, const char *name) { BSON_ASSERT (client); BSON_ASSERT (name); return _mongoc_database_new(client, name, client->read_prefs, client->read_concern, client->write_concern); } /* *-------------------------------------------------------------------------- * * mongoc_client_get_default_database -- * * Get the database named in the MongoDB connection URI, or NULL * if none was specified in the URI. * * This structure should be freed when the caller is done with it * using mongoc_database_destroy(). * * Returns: * A newly allocated mongoc_database_t or NULL. * * Side effects: * None. * *-------------------------------------------------------------------------- */ mongoc_database_t * mongoc_client_get_default_database (mongoc_client_t *client) { const char *db; BSON_ASSERT (client); db = mongoc_uri_get_database (client->uri); if (db) { return mongoc_client_get_database (client, db); } return NULL; } /* *-------------------------------------------------------------------------- * * mongoc_client_get_collection -- * * This function returns a newly allocated collection structure. * * @db should be the name of the database, such as "test". * @collection should be the name of the collection such as "test". * * The above would result in the namespace "test.test". * * You should free this structure when you are done with it using * mongoc_collection_destroy(). * * Returns: * A newly allocated mongoc_collection_t that should be freed with * mongoc_collection_destroy(). * * Side effects: * None. * *-------------------------------------------------------------------------- */ mongoc_collection_t * mongoc_client_get_collection (mongoc_client_t *client, const char *db, const char *collection) { BSON_ASSERT (client); BSON_ASSERT (db); BSON_ASSERT (collection); return _mongoc_collection_new(client, db, collection, client->read_prefs, client->read_concern, client->write_concern); } /* *-------------------------------------------------------------------------- * * mongoc_client_get_gridfs -- * * This function returns a newly allocated collection structure. * * @db should be the name of the database, such as "test". * * @prefix optional prefix for GridFS collection names, or NULL. Default * is "fs", thus the default collection names for GridFS are "fs.files" * and "fs.chunks". * * Returns: * A newly allocated mongoc_gridfs_t that should be freed with * mongoc_gridfs_destroy(). * * Side effects: * None. * *-------------------------------------------------------------------------- */ mongoc_gridfs_t * mongoc_client_get_gridfs (mongoc_client_t *client, const char *db, const char *prefix, bson_error_t *error) { BSON_ASSERT (client); BSON_ASSERT (db); if (! prefix) { prefix = "fs"; } return _mongoc_gridfs_new(client, db, prefix, error); } /* *-------------------------------------------------------------------------- * * mongoc_client_get_write_concern -- * * Fetches the default write concern for @client. * * Returns: * A mongoc_write_concern_t that should not be modified or freed. * * Side effects: * None. * *-------------------------------------------------------------------------- */ const mongoc_write_concern_t * mongoc_client_get_write_concern (const mongoc_client_t *client) { BSON_ASSERT (client); return client->write_concern; } /* *-------------------------------------------------------------------------- * * mongoc_client_set_write_concern -- * * Sets the default write concern for @client. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void mongoc_client_set_write_concern (mongoc_client_t *client, const mongoc_write_concern_t *write_concern) { BSON_ASSERT (client); if (write_concern != client->write_concern) { if (client->write_concern) { mongoc_write_concern_destroy(client->write_concern); } client->write_concern = write_concern ? mongoc_write_concern_copy(write_concern) : mongoc_write_concern_new(); } } /* *-------------------------------------------------------------------------- * * mongoc_client_get_read_concern -- * * Fetches the default read concern for @client. * * Returns: * A mongoc_read_concern_t that should not be modified or freed. * * Side effects: * None. * *-------------------------------------------------------------------------- */ const mongoc_read_concern_t * mongoc_client_get_read_concern (const mongoc_client_t *client) { BSON_ASSERT (client); return client->read_concern; } /* *-------------------------------------------------------------------------- * * mongoc_client_set_read_concern -- * * Sets the default read concern for @client. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void mongoc_client_set_read_concern (mongoc_client_t *client, const mongoc_read_concern_t *read_concern) { BSON_ASSERT (client); if (read_concern != client->read_concern) { if (client->read_concern) { mongoc_read_concern_destroy (client->read_concern); } client->read_concern = read_concern ? mongoc_read_concern_copy (read_concern) : mongoc_read_concern_new (); } } /* *-------------------------------------------------------------------------- * * mongoc_client_get_read_prefs -- * * Fetch the default read preferences for @client. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ const mongoc_read_prefs_t * mongoc_client_get_read_prefs (const mongoc_client_t *client) { BSON_ASSERT (client); return client->read_prefs; } /* *-------------------------------------------------------------------------- * * mongoc_client_set_read_prefs -- * * Set the default read preferences for @client. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void mongoc_client_set_read_prefs (mongoc_client_t *client, const mongoc_read_prefs_t *read_prefs) { BSON_ASSERT (client); if (read_prefs != client->read_prefs) { if (client->read_prefs) { mongoc_read_prefs_destroy(client->read_prefs); } client->read_prefs = read_prefs ? mongoc_read_prefs_copy(read_prefs) : mongoc_read_prefs_new(MONGOC_READ_PRIMARY); } } mongoc_cursor_t * mongoc_client_command (mongoc_client_t *client, const char *db_name, mongoc_query_flags_t flags, uint32_t skip, uint32_t limit, uint32_t batch_size, const bson_t *query, const bson_t *fields, const mongoc_read_prefs_t *read_prefs) { char ns[MONGOC_NAMESPACE_MAX]; BSON_ASSERT (client); BSON_ASSERT (db_name); BSON_ASSERT (query); if (!read_prefs) { read_prefs = client->read_prefs; } /* * Allow a caller to provide a fully qualified namespace */ if (NULL == strstr (db_name, "$cmd")) { bson_snprintf (ns, sizeof ns, "%s.$cmd", db_name); db_name = ns; } return _mongoc_cursor_new (client, db_name, flags, skip, limit, batch_size, true, query, fields, read_prefs, NULL); } /** * mongoc_client_command_simple: * @client: A mongoc_client_t. * @db_name: The namespace, such as "admin". * @command: The command to execute. * @read_prefs: The read preferences or NULL. * @reply: A location for the reply document or NULL. * @error: A location for the error, or NULL. * * This wrapper around mongoc_client_command() aims to make it simpler to * run a command and check the output result. * * false is returned if the command failed to be delivered or if the execution * of the command failed. For example, a command that returns {'ok': 0} will * result in this function returning false. * * To allow the caller to disambiguate between command execution failure and * failure to send the command, reply will always be set if non-NULL. The * caller should release this with bson_destroy(). * * Returns: true if the command executed and resulted in success. Otherwise * false and @error is set. @reply is always set, either to the resulting * document or an empty bson document upon failure. */ bool mongoc_client_command_simple (mongoc_client_t *client, const char *db_name, const bson_t *command, const mongoc_read_prefs_t *read_prefs, bson_t *reply, bson_error_t *error) { mongoc_cluster_t *cluster; mongoc_server_stream_t *server_stream; mongoc_apply_read_prefs_result_t result = READ_PREFS_RESULT_INIT; bool ret = false; ENTRY; BSON_ASSERT (client); BSON_ASSERT (db_name); BSON_ASSERT (command); cluster = &client->cluster; server_stream = mongoc_cluster_stream_for_reads (cluster, read_prefs, error); if (!server_stream) { if (reply) { bson_init (reply); } GOTO (done); } apply_read_preferences (read_prefs, server_stream, command, MONGOC_QUERY_NONE, &result); ret = mongoc_cluster_run_command (cluster, server_stream->stream, server_stream->sd->id, result.flags, db_name, result.query_with_read_prefs, reply, error); done: mongoc_server_stream_cleanup (server_stream); apply_read_prefs_result_cleanup (&result); RETURN (ret); } void _mongoc_client_kill_cursor (mongoc_client_t *client, uint32_t server_id, int64_t cursor_id, const char *db, const char *collection) { mongoc_server_stream_t *server_stream; ENTRY; BSON_ASSERT (client); BSON_ASSERT (cursor_id); /* don't attempt reconnect if server unavailable, and ignore errors */ server_stream = mongoc_cluster_stream_for_server (&client->cluster, server_id, false /* reconnect_ok */, NULL /* error */); if (!server_stream) { return; } if (db && collection && server_stream->sd->max_wire_version >= WIRE_VERSION_KILLCURSORS_CMD) { _mongoc_client_killcursors_command (&client->cluster, server_stream, cursor_id, db, collection); } else { _mongoc_client_op_killcursors (&client->cluster, server_stream, cursor_id); } mongoc_server_stream_cleanup (server_stream); EXIT; } static void _mongoc_client_op_killcursors (mongoc_cluster_t *cluster, mongoc_server_stream_t *server_stream, int64_t cursor_id) { mongoc_rpc_t rpc = { { 0 } }; rpc.kill_cursors.msg_len = 0; rpc.kill_cursors.request_id = 0; rpc.kill_cursors.response_to = 0; rpc.kill_cursors.opcode = MONGOC_OPCODE_KILL_CURSORS; rpc.kill_cursors.zero = 0; rpc.kill_cursors.cursors = &cursor_id; rpc.kill_cursors.n_cursors = 1; mongoc_cluster_sendv_to_server (cluster, &rpc, 1, server_stream, NULL, NULL); } static void _mongoc_client_killcursors_command (mongoc_cluster_t *cluster, mongoc_server_stream_t *server_stream, int64_t cursor_id, const char *db, const char *collection) { bson_t command = BSON_INITIALIZER; bson_t child; bson_append_utf8 (&command, "killCursors", 11, collection, -1); bson_append_array_begin (&command, "cursors", 7, &child); bson_append_int64 (&child, "0", 1, cursor_id); bson_append_array_end (&command, &child); /* Find, getMore And killCursors Commands Spec: "The result from the * killCursors command MAY be safely ignored." */ mongoc_cluster_run_command (cluster, server_stream->stream, server_stream->sd->id, MONGOC_QUERY_SLAVE_OK, db, &command, NULL, NULL); bson_destroy (&command); } /* *-------------------------------------------------------------------------- * * mongoc_client_kill_cursor -- * * Destroy a cursor on the server. * * NOTE: this is only reliable when connected to a single mongod or * mongos. If connected to a replica set, the driver attempts to * kill the cursor on the primary. If connected to multiple mongoses * the kill-cursors message is sent to a *random* mongos. * * If no primary, mongos, or standalone server is known, return * without attempting to reconnect. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void mongoc_client_kill_cursor (mongoc_client_t *client, int64_t cursor_id) { mongoc_topology_t *topology; mongoc_server_description_t *selected_server; mongoc_read_prefs_t *read_prefs; uint32_t server_id = 0; topology = client->topology; read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); mongoc_mutex_lock (&topology->mutex); /* see if there's a known writable server - do no I/O or retries */ selected_server = mongoc_topology_description_select(&topology->description, MONGOC_SS_WRITE, read_prefs, 15); if (selected_server) { server_id = selected_server->id; } mongoc_mutex_unlock (&topology->mutex); if (server_id) { _mongoc_client_kill_cursor (client, selected_server->id, cursor_id, NULL /* db */, NULL /* collection */); } else { MONGOC_INFO ("No server available for mongoc_client_kill_cursor"); } mongoc_read_prefs_destroy (read_prefs); } char ** mongoc_client_get_database_names (mongoc_client_t *client, bson_error_t *error) { bson_iter_t iter; const char *name; char **ret = NULL; int i = 0; mongoc_cursor_t *cursor; const bson_t *doc; BSON_ASSERT (client); cursor = mongoc_client_find_databases (client, error); while (mongoc_cursor_next (cursor, &doc)) { if (bson_iter_init (&iter, doc) && bson_iter_find (&iter, "name") && BSON_ITER_HOLDS_UTF8 (&iter) && (name = bson_iter_utf8 (&iter, NULL)) && (0 != strcmp (name, "local"))) { ret = (char **)bson_realloc (ret, sizeof(char*) * (i + 2)); ret [i] = bson_strdup (name); ret [++i] = NULL; } } if (!ret && !mongoc_cursor_error (cursor, error)) { ret = (char **)bson_malloc0 (sizeof (void*)); } mongoc_cursor_destroy (cursor); return ret; } mongoc_cursor_t * mongoc_client_find_databases (mongoc_client_t *client, bson_error_t *error) { bson_t cmd = BSON_INITIALIZER; mongoc_cursor_t *cursor; BSON_ASSERT (client); BSON_APPEND_INT32 (&cmd, "listDatabases", 1); cursor = _mongoc_cursor_new (client, "admin", MONGOC_QUERY_SLAVE_OK, 0, 0, 0, true, NULL, NULL, NULL, NULL); _mongoc_cursor_array_init (cursor, &cmd, "databases"); bson_destroy (&cmd); return cursor; } int32_t mongoc_client_get_max_message_size (mongoc_client_t *client) /* IN */ { BSON_ASSERT (client); return mongoc_cluster_get_max_msg_size (&client->cluster); } int32_t mongoc_client_get_max_bson_size (mongoc_client_t *client) /* IN */ { BSON_ASSERT (client); return mongoc_cluster_get_max_bson_obj_size (&client->cluster); } bool mongoc_client_get_server_status (mongoc_client_t *client, /* IN */ mongoc_read_prefs_t *read_prefs, /* IN */ bson_t *reply, /* OUT */ bson_error_t *error) /* OUT */ { bson_t cmd = BSON_INITIALIZER; bool ret = false; BSON_ASSERT (client); BSON_APPEND_INT32 (&cmd, "serverStatus", 1); ret = mongoc_client_command_simple (client, "admin", &cmd, read_prefs, reply, error); bson_destroy (&cmd); return ret; } void mongoc_client_set_stream_initiator (mongoc_client_t *client, mongoc_stream_initiator_t initiator, void *user_data) { BSON_ASSERT (client); if (!initiator) { initiator = mongoc_client_default_stream_initiator; user_data = client; } else { MONGOC_DEBUG ("Using custom stream initiator."); } client->initiator = initiator; client->initiator_data = user_data; if (client->topology->single_threaded) { mongoc_topology_scanner_set_stream_initiator (client->topology->scanner, initiator, user_data); } } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-client.h0000664000175000017500000002116412673034026022532 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_CLIENT_H #define MONGOC_CLIENT_H #if !defined (MONGOC_INSIDE) && !defined (MONGOC_COMPILATION) # error "Only can be included directly." #endif #include #include "mongoc-collection.h" #include "mongoc-config.h" #include "mongoc-cursor.h" #include "mongoc-database.h" #include "mongoc-gridfs.h" #include "mongoc-index.h" #include "mongoc-read-prefs.h" #ifdef MONGOC_ENABLE_SSL # include "mongoc-ssl.h" #endif #include "mongoc-stream.h" #include "mongoc-uri.h" #include "mongoc-write-concern.h" #include "mongoc-read-concern.h" BSON_BEGIN_DECLS #define MONGOC_NAMESPACE_MAX 128 #ifndef MONGOC_DEFAULT_CONNECTTIMEOUTMS #define MONGOC_DEFAULT_CONNECTTIMEOUTMS (10 * 1000L) #endif #ifndef MONGOC_DEFAULT_SOCKETTIMEOUTMS /* * NOTE: The default socket timeout for connections is 5 minutes. This * means that if your MongoDB server dies or becomes unavailable * it will take 5 minutes to detect this. * * You can change this by providing sockettimeoutms= in your * connection URI. */ #define MONGOC_DEFAULT_SOCKETTIMEOUTMS (1000L * 60L * 5L) #endif /** * mongoc_client_t: * * The mongoc_client_t structure maintains information about a connection to * a MongoDB server. */ typedef struct _mongoc_client_t mongoc_client_t; /** * mongoc_stream_initiator_t: * @uri: The uri and options for the stream. * @host: The host and port (or UNIX domain socket path) to connect to. * @user_data: The pointer passed to mongoc_client_set_stream_initiator. * @error: A location for an error. * * Creates a new mongoc_stream_t for the host and port. Begin a * non-blocking connect and return immediately. * * This can be used by language bindings to create network transports other * than those built into libmongoc. An example of such would be the streams * API provided by PHP. * * Returns: A newly allocated mongoc_stream_t or NULL on failure. */ typedef mongoc_stream_t *(*mongoc_stream_initiator_t) (const mongoc_uri_t *uri, const mongoc_host_list_t *host, void *user_data, bson_error_t *error); mongoc_client_t *mongoc_client_new (const char *uri_string); mongoc_client_t *mongoc_client_new_from_uri (const mongoc_uri_t *uri); const mongoc_uri_t *mongoc_client_get_uri (const mongoc_client_t *client); void mongoc_client_set_stream_initiator (mongoc_client_t *client, mongoc_stream_initiator_t initiator, void *user_data); mongoc_cursor_t *mongoc_client_command (mongoc_client_t *client, const char *db_name, mongoc_query_flags_t flags, uint32_t skip, uint32_t limit, uint32_t batch_size, const bson_t *query, const bson_t *fields, const mongoc_read_prefs_t *read_prefs); void mongoc_client_kill_cursor (mongoc_client_t *client, int64_t cursor_id) BSON_GNUC_DEPRECATED; bool mongoc_client_command_simple (mongoc_client_t *client, const char *db_name, const bson_t *command, const mongoc_read_prefs_t *read_prefs, bson_t *reply, bson_error_t *error); void mongoc_client_destroy (mongoc_client_t *client); mongoc_database_t *mongoc_client_get_database (mongoc_client_t *client, const char *name); mongoc_database_t *mongoc_client_get_default_database (mongoc_client_t *client); mongoc_gridfs_t *mongoc_client_get_gridfs (mongoc_client_t *client, const char *db, const char *prefix, bson_error_t *error); mongoc_collection_t *mongoc_client_get_collection (mongoc_client_t *client, const char *db, const char *collection); char **mongoc_client_get_database_names (mongoc_client_t *client, bson_error_t *error); mongoc_cursor_t *mongoc_client_find_databases (mongoc_client_t *client, bson_error_t *error); bool mongoc_client_get_server_status (mongoc_client_t *client, mongoc_read_prefs_t *read_prefs, bson_t *reply, bson_error_t *error); int32_t mongoc_client_get_max_message_size (mongoc_client_t *client) BSON_GNUC_DEPRECATED; int32_t mongoc_client_get_max_bson_size (mongoc_client_t *client) BSON_GNUC_DEPRECATED; const mongoc_write_concern_t *mongoc_client_get_write_concern (const mongoc_client_t *client); void mongoc_client_set_write_concern (mongoc_client_t *client, const mongoc_write_concern_t *write_concern); const mongoc_read_concern_t *mongoc_client_get_read_concern (const mongoc_client_t *client); void mongoc_client_set_read_concern (mongoc_client_t *client, const mongoc_read_concern_t *read_concern); const mongoc_read_prefs_t *mongoc_client_get_read_prefs (const mongoc_client_t *client); void mongoc_client_set_read_prefs (mongoc_client_t *client, const mongoc_read_prefs_t *read_prefs); #ifdef MONGOC_ENABLE_SSL void mongoc_client_set_ssl_opts (mongoc_client_t *client, const mongoc_ssl_opt_t *opts); #endif BSON_END_DECLS #endif /* MONGOC_CLIENT_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-cluster-private.h0000664000175000017500000001163512673034026024407 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_CLUSTER_PRIVATE_H #define MONGOC_CLUSTER_PRIVATE_H #if !defined (MONGOC_I_AM_A_DRIVER) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #include #include "mongoc-array-private.h" #include "mongoc-buffer-private.h" #include "mongoc-config.h" #include "mongoc-client.h" #include "mongoc-list-private.h" #include "mongoc-opcode.h" #include "mongoc-read-prefs.h" #include "mongoc-rpc-private.h" #include "mongoc-server-stream-private.h" #include "mongoc-set-private.h" #include "mongoc-stream.h" #include "mongoc-topology-description-private.h" #include "mongoc-uri.h" #include "mongoc-write-concern.h" BSON_BEGIN_DECLS typedef struct _mongoc_cluster_node_t { mongoc_stream_t *stream; int32_t max_wire_version; int32_t min_wire_version; int32_t max_write_batch_size; int32_t max_bson_obj_size; int32_t max_msg_size; int64_t timestamp; } mongoc_cluster_node_t; typedef struct _mongoc_cluster_t { uint32_t request_id; uint32_t sockettimeoutms; uint32_t socketcheckintervalms; mongoc_uri_t *uri; unsigned requires_auth : 1; mongoc_client_t *client; mongoc_set_t *nodes; mongoc_array_t iov; } mongoc_cluster_t; void mongoc_cluster_init (mongoc_cluster_t *cluster, const mongoc_uri_t *uri, void *client); void mongoc_cluster_destroy (mongoc_cluster_t *cluster); void mongoc_cluster_disconnect_node (mongoc_cluster_t *cluster, uint32_t id); int32_t mongoc_cluster_get_max_bson_obj_size (mongoc_cluster_t *cluster); int32_t mongoc_cluster_get_max_msg_size (mongoc_cluster_t *cluster); int32_t mongoc_cluster_node_max_wire_version (mongoc_cluster_t *cluster, uint32_t server_id); int32_t mongoc_cluster_node_min_wire_version (mongoc_cluster_t *cluster, uint32_t server_id); bool mongoc_cluster_sendv_to_server (mongoc_cluster_t *cluster, mongoc_rpc_t *rpcs, size_t rpcs_len, mongoc_server_stream_t *server_stream, const mongoc_write_concern_t *write_concern, bson_error_t *error); bool mongoc_cluster_try_recv (mongoc_cluster_t *cluster, mongoc_rpc_t *rpc, mongoc_buffer_t *buffer, mongoc_server_stream_t *server_stream, bson_error_t *error); mongoc_server_stream_t * mongoc_cluster_stream_for_reads (mongoc_cluster_t *cluster, const mongoc_read_prefs_t *read_prefs, bson_error_t *error); mongoc_server_stream_t * mongoc_cluster_stream_for_writes (mongoc_cluster_t *cluster, bson_error_t *error); mongoc_server_stream_t * mongoc_cluster_stream_for_server (mongoc_cluster_t *cluster, uint32_t server_id, bool reconnect_ok, bson_error_t *error); bool mongoc_cluster_run_command_rpc (mongoc_cluster_t *cluster, mongoc_stream_t *stream, uint32_t server_id, const char *command_name, mongoc_rpc_t *rpc, mongoc_rpc_t *reply_rpc, mongoc_buffer_t *buffer, bson_error_t *error); bool mongoc_cluster_run_command (mongoc_cluster_t *cluster, mongoc_stream_t *stream, uint32_t server_id, mongoc_query_flags_t flags, const char *db_name, const bson_t *command, bson_t *reply, bson_error_t *error); BSON_END_DECLS #endif /* MONGOC_CLUSTER_PRIVATE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-cluster.c0000664000175000017500000021001312673034026022721 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "mongoc-config.h" #ifdef MONGOC_ENABLE_SASL #include #include #endif #include #include "mongoc-cluster-private.h" #include "mongoc-client-private.h" #include "mongoc-counters-private.h" #include "mongoc-config.h" #include "mongoc-error.h" #include "mongoc-host-list-private.h" #include "mongoc-log.h" #ifdef MONGOC_ENABLE_SASL #include "mongoc-sasl-private.h" #endif #include "mongoc-b64-private.h" #include "mongoc-scram-private.h" #include "mongoc-set-private.h" #include "mongoc-socket.h" #include "mongoc-stream-private.h" #include "mongoc-stream-socket.h" #include "mongoc-thread-private.h" #include "mongoc-topology-private.h" #include "mongoc-trace.h" #include "mongoc-util-private.h" #include "mongoc-write-concern-private.h" #include "mongoc-uri-private.h" #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "cluster" #define CHECK_CLOSED_DURATION_MSEC 1000 #define DB_AND_CMD_FROM_COLLECTION(outstr, name) \ do { \ const char *dot = strchr(name, '.'); \ if (!dot || ((dot - name) > (sizeof outstr - 6))) { \ bson_snprintf(outstr, sizeof outstr, "admin.$cmd"); \ } else { \ memcpy(outstr, name, dot - name); \ memcpy(outstr + (dot - name), ".$cmd", 6); \ } \ } while (0) static mongoc_server_stream_t * mongoc_cluster_fetch_stream_single (mongoc_cluster_t *cluster, mongoc_server_description_t *sd, bool reconnect_ok, bson_error_t *error); static mongoc_server_stream_t * mongoc_cluster_fetch_stream_pooled (mongoc_cluster_t *cluster, mongoc_server_description_t *sd, bool reconnect_ok, bson_error_t *error); static void _bson_error_message_printf (bson_error_t *error, const char *format, ...) BSON_GNUC_PRINTF (2, 3); /* Allows caller to safely overwrite error->message with a formatted string, * even if the formatted string includes original error->message. */ static void _bson_error_message_printf (bson_error_t *error, const char *format, ...) { va_list args; char error_message[sizeof error->message]; if (error) { va_start (args, format); bson_vsnprintf (error_message, sizeof error->message, format, args); va_end (args); bson_strncpy (error->message, error_message, sizeof error->message); } } /* *-------------------------------------------------------------------------- * * mongoc_cluster_run_command_rpc -- * * Internal function to run a command on a given stream and * read the response into @reply_rpc. @rpc and @reply_rpc can be * the same to reuse storage. @buffer should be initialized before * passing it in. * * Returns: * true if successful; otherwise false and @error is set. * * Side effects: * On success, @buffer and @reply_rpc are filled out with the reply. * On failure, @error is filled out. If this was a network error * and server_id is nonzero, the cluster disconnects from the server. * *-------------------------------------------------------------------------- */ bool mongoc_cluster_run_command_rpc (mongoc_cluster_t *cluster, mongoc_stream_t *stream, uint32_t server_id, const char *command_name, mongoc_rpc_t *rpc, mongoc_rpc_t *reply_rpc, mongoc_buffer_t *buffer, bson_error_t *error) { mongoc_array_t ar; int32_t msg_len; bool error_set = false; bool ret = false; char db[MONGOC_NAMESPACE_MAX]; ENTRY; BSON_ASSERT(cluster); BSON_ASSERT(stream); _mongoc_array_init (&ar, sizeof (mongoc_iovec_t)); if (cluster->client->in_exhaust) { bson_set_error(error, MONGOC_ERROR_CLIENT, MONGOC_ERROR_CLIENT_IN_EXHAUST, "A cursor derived from this client is in exhaust."); error_set = true; GOTO (done); } rpc->query.request_id = ++cluster->request_id; _mongoc_rpc_gather (rpc, &ar); _mongoc_rpc_swab_to_le (rpc); if (!_mongoc_stream_writev_full (stream, (mongoc_iovec_t *)ar.data, ar.len, cluster->sockettimeoutms, error) || !_mongoc_buffer_append_from_stream (buffer, stream, 4, cluster->sockettimeoutms, error)) { mongoc_cluster_disconnect_node (cluster, server_id); /* add info about the command to writev_full's error message */ _mongoc_get_db_name (rpc->query.collection, db); _bson_error_message_printf ( error, "Failed to send \"%s\" command with database \"%s\": %s", command_name, db, error->message); error_set = true; GOTO (done); } BSON_ASSERT (buffer->len == 4); memcpy (&msg_len, buffer->data, 4); msg_len = BSON_UINT32_FROM_LE(msg_len); if ((msg_len < 16) || (msg_len > MONGOC_DEFAULT_MAX_MSG_SIZE)) { GOTO (done); } if (!_mongoc_buffer_append_from_stream (buffer, stream, (size_t) msg_len - 4, cluster->sockettimeoutms, error)) { error_set = true; GOTO (done); } if (!_mongoc_rpc_scatter (reply_rpc, buffer->data, buffer->len)) { GOTO (done); } _mongoc_rpc_swab_from_le (reply_rpc); if (reply_rpc->header.opcode != MONGOC_OPCODE_REPLY) { GOTO (done); } ret = true; done: _mongoc_array_destroy (&ar); if (!ret && !error_set) { /* generic error */ bson_set_error (error, MONGOC_ERROR_PROTOCOL, MONGOC_ERROR_PROTOCOL_INVALID_REPLY, "Invalid reply from server."); } RETURN (ret); } /* *-------------------------------------------------------------------------- * * mongoc_cluster_run_command -- * * Internal function to run a command on a given stream. * @error and @reply are optional out-pointers. * * Returns: * true if successful; otherwise false and @error is set. * * Side effects: * @reply is set and should ALWAYS be released with bson_destroy(). * On failure, @error is filled out. If this was a network error * and server_id is nonzero, the cluster disconnects from the server. * *-------------------------------------------------------------------------- */ bool mongoc_cluster_run_command (mongoc_cluster_t *cluster, mongoc_stream_t *stream, uint32_t server_id, mongoc_query_flags_t flags, const char *db_name, const bson_t *command, bson_t *reply, bson_error_t *error) { char ns[MONGOC_NAMESPACE_MAX]; mongoc_rpc_t rpc; bson_t reply_local; bool ret = false; bool reply_local_initialized = false; mongoc_buffer_t buffer; _mongoc_buffer_init (&buffer, NULL, 0, NULL, NULL); bson_snprintf (ns, sizeof ns, "%s.$cmd", db_name); _mongoc_rpc_prep_command (&rpc, ns, command, flags); /* we can reuse the query rpc for the reply */ if (!mongoc_cluster_run_command_rpc (cluster, stream, server_id, _mongoc_get_command_name (command), &rpc, &rpc, &buffer, error)) { GOTO (done); } /* static-init reply_local to point into buffer */ if (!_mongoc_rpc_reply_get_first(&rpc.reply, &reply_local)) { bson_set_error (error, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, "Failed to decode reply BSON document."); GOTO (done); } reply_local_initialized = true; if (_mongoc_rpc_parse_command_error (&rpc, error)) { GOTO (done); } ret = true; done: if (reply && reply_local_initialized) { bson_copy_to (&reply_local, reply); bson_destroy (&reply_local); } else if (reply) { bson_init (reply); } _mongoc_buffer_destroy (&buffer); RETURN (ret); } /* *-------------------------------------------------------------------------- * * _mongoc_stream_run_ismaster -- * * Run an ismaster command on the given stream. * * Returns: * True if ismaster ran successfully. * * Side effects: * Makes a blocking I/O call and fills out @reply on success, * or @error on failure. * *-------------------------------------------------------------------------- */ static bool _mongoc_stream_run_ismaster (mongoc_cluster_t *cluster, mongoc_stream_t *stream, bson_t *reply, bson_error_t *error) { bson_t command; bool ret; ENTRY; BSON_ASSERT (cluster); BSON_ASSERT (stream); BSON_ASSERT (reply); BSON_ASSERT (error); bson_init (&command); bson_append_int32 (&command, "ismaster", 8, 1); ret = mongoc_cluster_run_command (cluster, stream, 0, MONGOC_QUERY_SLAVE_OK, "admin", &command, reply, error); bson_destroy (&command); RETURN (ret); } /* *-------------------------------------------------------------------------- * * _mongoc_cluster_run_ismaster -- * * Run an ismaster command for the given node and handle result. * * Returns: * True if ismaster ran successfully, false otherwise. * * Side effects: * Makes a blocking I/O call. * *-------------------------------------------------------------------------- */ static bool _mongoc_cluster_run_ismaster (mongoc_cluster_t *cluster, mongoc_cluster_node_t *node) { bson_t reply; bson_error_t error; bson_iter_t iter; int num_fields = 0; ENTRY; BSON_ASSERT (cluster); BSON_ASSERT (node); BSON_ASSERT (node->stream); if (!_mongoc_stream_run_ismaster (cluster, node->stream, &reply, &error)) { GOTO (failure); } bson_iter_init (&iter, &reply); while (bson_iter_next (&iter)) { num_fields++; if (strcmp ("maxWriteBatchSize", bson_iter_key (&iter)) == 0) { if (! BSON_ITER_HOLDS_INT32 (&iter)) goto failure; node->max_write_batch_size = bson_iter_int32 (&iter); } else if (strcmp ("minWireVersion", bson_iter_key (&iter)) == 0) { if (! BSON_ITER_HOLDS_INT32 (&iter)) goto failure; node->min_wire_version = bson_iter_int32 (&iter); } else if (strcmp ("maxWireVersion", bson_iter_key (&iter)) == 0) { if (! BSON_ITER_HOLDS_INT32 (&iter)) goto failure; node->max_wire_version = bson_iter_int32 (&iter); } else if (strcmp ("maxBsonObjSize", bson_iter_key (&iter)) == 0) { if (! BSON_ITER_HOLDS_INT32 (&iter)) goto failure; node->max_bson_obj_size = bson_iter_int32 (&iter); } else if (strcmp ("maxMessageSizeBytes", bson_iter_key (&iter)) == 0) { if (! BSON_ITER_HOLDS_INT32 (&iter)) goto failure; node->max_msg_size = bson_iter_int32 (&iter); } } if (num_fields == 0) goto failure; /* TODO: run ismaster through the topology machinery? */ bson_destroy (&reply); return true; failure: bson_destroy (&reply); return false; } /* *-------------------------------------------------------------------------- * * _mongoc_cluster_build_basic_auth_digest -- * * Computes the Basic Authentication digest using the credentials * configured for @cluster and the @nonce provided. * * The result should be freed by the caller using bson_free() when * they are finished with it. * * Returns: * A newly allocated string containing the digest. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static char * _mongoc_cluster_build_basic_auth_digest (mongoc_cluster_t *cluster, const char *nonce) { const char *username; const char *password; char *password_digest; char *password_md5; char *digest_in; char *ret; ENTRY; /* * The following generates the digest to be used for basic authentication * with a MongoDB server. More information on the format can be found * at the following location: * * http://docs.mongodb.org/meta-driver/latest/legacy/ * implement-authentication-in-driver/ */ BSON_ASSERT(cluster); BSON_ASSERT(cluster->uri); username = mongoc_uri_get_username(cluster->uri); password = mongoc_uri_get_password(cluster->uri); password_digest = bson_strdup_printf("%s:mongo:%s", username, password); password_md5 = _mongoc_hex_md5(password_digest); digest_in = bson_strdup_printf("%s%s%s", nonce, username, password_md5); ret = _mongoc_hex_md5(digest_in); bson_free(digest_in); bson_free(password_md5); bson_free(password_digest); RETURN(ret); } /* *-------------------------------------------------------------------------- * * _mongoc_cluster_auth_node_cr -- * * Performs authentication of @node using the credentials provided * when configuring the @cluster instance. * * This is the Challenge-Response mode of authentication. * * Returns: * true if authentication was successful; otherwise false and * @error is set. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static bool _mongoc_cluster_auth_node_cr (mongoc_cluster_t *cluster, mongoc_stream_t *stream, bson_error_t *error) { bson_iter_t iter; const char *auth_source; bson_t command = { 0 }; bson_t reply = { 0 }; char *digest; char *nonce; bool ret; ENTRY; BSON_ASSERT(cluster); BSON_ASSERT(stream); if (!(auth_source = mongoc_uri_get_auth_source(cluster->uri)) || (*auth_source == '\0')) { auth_source = "admin"; } /* * To authenticate a node using basic authentication, we need to first * get the nonce from the server. We use that to hash our password which * is sent as a reply to the server. If everything went good we get a * success notification back from the server. */ /* * Execute the getnonce command to fetch the nonce used for generating * md5 digest of our password information. */ bson_init (&command); bson_append_int32 (&command, "getnonce", 8, 1); if (!mongoc_cluster_run_command (cluster, stream, 0, MONGOC_QUERY_SLAVE_OK, auth_source, &command, &reply, error)) { bson_destroy (&command); bson_destroy (&reply); RETURN (false); } bson_destroy (&command); if (!bson_iter_init_find_case (&iter, &reply, "nonce")) { bson_set_error (error, MONGOC_ERROR_CLIENT, MONGOC_ERROR_CLIENT_GETNONCE, "Invalid reply from getnonce"); bson_destroy (&reply); RETURN (false); } /* * Build our command to perform the authentication. */ nonce = bson_iter_dup_utf8(&iter, NULL); digest = _mongoc_cluster_build_basic_auth_digest(cluster, nonce); bson_init(&command); bson_append_int32(&command, "authenticate", 12, 1); bson_append_utf8(&command, "user", 4, mongoc_uri_get_username(cluster->uri), -1); bson_append_utf8(&command, "nonce", 5, nonce, -1); bson_append_utf8(&command, "key", 3, digest, -1); bson_destroy(&reply); bson_free(nonce); bson_free(digest); /* * Execute the authenticate command. mongoc_cluster_run_command * checks for {ok: 1} in the response. */ ret = mongoc_cluster_run_command (cluster, stream, 0, MONGOC_QUERY_SLAVE_OK, auth_source, &command, &reply, error); if (!ret) { /* error->message is already set */ error->domain = MONGOC_ERROR_CLIENT; error->code = MONGOC_ERROR_CLIENT_AUTHENTICATE; } bson_destroy (&command); bson_destroy (&reply); RETURN (ret); } #ifdef MONGOC_ENABLE_SASL /* *-------------------------------------------------------------------------- * * _mongoc_cluster_get_canonicalized_name -- * * Query the node to get the canonicalized name. This may happen if * the node has been accessed via an alias. * * The gssapi code will use this if canonicalizeHostname is true. * * Some underlying layers of krb might do this for us, but they can * be disabled in krb.conf. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static bool _mongoc_cluster_get_canonicalized_name (mongoc_cluster_t *cluster, /* IN */ mongoc_stream_t *node_stream, /* IN */ char *name, /* OUT */ size_t namelen, /* IN */ bson_error_t *error) /* OUT */ { mongoc_stream_t *stream; mongoc_stream_t *tmp; mongoc_socket_t *sock = NULL; char *canonicalized; ENTRY; BSON_ASSERT (cluster); BSON_ASSERT (node_stream); BSON_ASSERT (name); /* * Find the underlying socket used in the stream chain. */ for (stream = node_stream; stream;) { if ((tmp = mongoc_stream_get_base_stream (stream))) { stream = tmp; continue; } break; } BSON_ASSERT (stream); if (stream->type == MONGOC_STREAM_SOCKET) { sock = mongoc_stream_socket_get_socket ((mongoc_stream_socket_t *)stream); if (sock) { canonicalized = mongoc_socket_getnameinfo (sock); if (canonicalized) { bson_snprintf (name, namelen, "%s", canonicalized); bson_free (canonicalized); RETURN (true); } } } RETURN (false); } #endif #ifdef MONGOC_ENABLE_SASL /* *-------------------------------------------------------------------------- * * _mongoc_cluster_auth_node_sasl -- * * Perform authentication for a cluster node using SASL. This is * only supported for GSSAPI at the moment. * * Returns: * true if successful; otherwise false and @error is set. * * Side effects: * error may be set. * *-------------------------------------------------------------------------- */ static bool _mongoc_cluster_auth_node_sasl (mongoc_cluster_t *cluster, mongoc_stream_t *stream, const char *hostname, bson_error_t *error) { uint32_t buflen = 0; mongoc_sasl_t sasl; const bson_t *options; bson_iter_t iter; bool ret = false; char real_name [BSON_HOST_NAME_MAX + 1]; const char *service_name; const char *mechanism; const char *tmpstr; uint8_t buf[4096] = { 0 }; bson_t cmd; bson_t reply; int conv_id = 0; BSON_ASSERT (cluster); BSON_ASSERT (stream); options = mongoc_uri_get_options (cluster->uri); _mongoc_sasl_init (&sasl); if ((mechanism = mongoc_uri_get_auth_mechanism (cluster->uri))) { _mongoc_sasl_set_mechanism (&sasl, mechanism); } if (bson_iter_init_find_case (&iter, options, "gssapiservicename") && BSON_ITER_HOLDS_UTF8 (&iter) && (service_name = bson_iter_utf8 (&iter, NULL))) { _mongoc_sasl_set_service_name (&sasl, service_name); } _mongoc_sasl_set_pass (&sasl, mongoc_uri_get_password (cluster->uri)); _mongoc_sasl_set_user (&sasl, mongoc_uri_get_username (cluster->uri)); /* * If the URI requested canonicalizeHostname, we need to resolve the real * hostname for the IP Address and pass that to the SASL layer. Some * underlying GSSAPI layers will do this for us, but can be disabled in * their config (krb.conf). * * This allows the consumer to specify canonicalizeHostname=true in the URI * and have us do that for them. * * See CDRIVER-323 for more information. */ if (bson_iter_init_find_case (&iter, options, "canonicalizeHostname") && BSON_ITER_HOLDS_BOOL (&iter) && bson_iter_bool (&iter)) { if (_mongoc_cluster_get_canonicalized_name (cluster, stream, real_name, sizeof real_name, error)) { _mongoc_sasl_set_service_host (&sasl, real_name); } else { _mongoc_sasl_set_service_host (&sasl, hostname); } } else { _mongoc_sasl_set_service_host (&sasl, hostname); } for (;;) { if (!_mongoc_sasl_step (&sasl, buf, buflen, buf, sizeof buf, &buflen, error)) { goto failure; } bson_init (&cmd); if (sasl.step == 1) { BSON_APPEND_INT32 (&cmd, "saslStart", 1); BSON_APPEND_UTF8 (&cmd, "mechanism", mechanism ? mechanism : "GSSAPI"); bson_append_utf8 (&cmd, "payload", 7, (const char *)buf, buflen); BSON_APPEND_INT32 (&cmd, "autoAuthorize", 1); } else { BSON_APPEND_INT32 (&cmd, "saslContinue", 1); BSON_APPEND_INT32 (&cmd, "conversationId", conv_id); bson_append_utf8 (&cmd, "payload", 7, (const char *)buf, buflen); } MONGOC_INFO ("SASL: authenticating \"%s\" (step %d)", mongoc_uri_get_username (cluster->uri), sasl.step); if (!mongoc_cluster_run_command (cluster, stream, 0, MONGOC_QUERY_SLAVE_OK, "$external", &cmd, &reply, error)) { bson_destroy (&cmd); bson_destroy (&reply); goto failure; } bson_destroy (&cmd); if (bson_iter_init_find (&iter, &reply, "done") && bson_iter_as_bool (&iter)) { bson_destroy (&reply); break; } if (!bson_iter_init_find (&iter, &reply, "conversationId") || !BSON_ITER_HOLDS_INT32 (&iter) || !(conv_id = bson_iter_int32 (&iter)) || !bson_iter_init_find (&iter, &reply, "payload") || !BSON_ITER_HOLDS_UTF8 (&iter)) { MONGOC_INFO ("SASL: authentication failed for \"%s\"", mongoc_uri_get_username (cluster->uri)); bson_destroy (&reply); bson_set_error (error, MONGOC_ERROR_CLIENT, MONGOC_ERROR_CLIENT_AUTHENTICATE, "Received invalid SASL reply from MongoDB server."); goto failure; } tmpstr = bson_iter_utf8 (&iter, &buflen); if (buflen > sizeof buf) { bson_set_error (error, MONGOC_ERROR_CLIENT, MONGOC_ERROR_CLIENT_AUTHENTICATE, "SASL reply from MongoDB is too large."); bson_destroy (&reply); goto failure; } memcpy (buf, tmpstr, buflen); bson_destroy (&reply); } MONGOC_INFO ("SASL: \"%s\" authenticated", mongoc_uri_get_username (cluster->uri)); ret = true; failure: _mongoc_sasl_destroy (&sasl); return ret; } #endif /* *-------------------------------------------------------------------------- * * _mongoc_cluster_auth_node_plain -- * * Perform SASL PLAIN authentication for @node. We do this manually * instead of using the SASL module because its rather simplistic. * * Returns: * true if successful; otherwise false and error is set. * * Side effects: * error may be set. * *-------------------------------------------------------------------------- */ static bool _mongoc_cluster_auth_node_plain (mongoc_cluster_t *cluster, mongoc_stream_t *stream, bson_error_t *error) { char buf[4096]; int buflen = 0; const char *username; const char *password; bson_t b = BSON_INITIALIZER; bson_t reply; size_t len; char *str; bool ret; BSON_ASSERT (cluster); BSON_ASSERT (stream); username = mongoc_uri_get_username (cluster->uri); if (!username) { username = ""; } password = mongoc_uri_get_password (cluster->uri); if (!password) { password = ""; } str = bson_strdup_printf ("%c%s%c%s", '\0', username, '\0', password); len = strlen (username) + strlen (password) + 2; buflen = mongoc_b64_ntop ((const uint8_t *) str, len, buf, sizeof buf); bson_free (str); if (buflen == -1) { bson_set_error (error, MONGOC_ERROR_CLIENT, MONGOC_ERROR_CLIENT_AUTHENTICATE, "failed base64 encoding message"); return false; } BSON_APPEND_INT32 (&b, "saslStart", 1); BSON_APPEND_UTF8 (&b, "mechanism", "PLAIN"); bson_append_utf8 (&b, "payload", 7, (const char *)buf, buflen); BSON_APPEND_INT32 (&b, "autoAuthorize", 1); ret = mongoc_cluster_run_command (cluster, stream, 0, MONGOC_QUERY_SLAVE_OK, "$external", &b, &reply, error); if (!ret) { /* error->message is already set */ error->domain = MONGOC_ERROR_CLIENT; error->code = MONGOC_ERROR_CLIENT_AUTHENTICATE; } bson_destroy (&b); bson_destroy (&reply); return ret; } #ifdef MONGOC_ENABLE_SSL static bool _mongoc_cluster_auth_node_x509 (mongoc_cluster_t *cluster, mongoc_stream_t *stream, bson_error_t *error) { const char *username; bson_t cmd; bson_t reply; bool ret; BSON_ASSERT (cluster); BSON_ASSERT (stream); username = mongoc_uri_get_username (cluster->uri); if (username) { MONGOC_INFO ("X509: got username (%s) from URI", username); } else { if (!cluster->client->ssl_opts.pem_file) { bson_set_error (error, MONGOC_ERROR_CLIENT, MONGOC_ERROR_CLIENT_AUTHENTICATE, "cannot determine username for " "X-509 authentication."); return false; } if (cluster->client->pem_subject) { username = cluster->client->pem_subject; MONGOC_INFO ("X509: got username (%s) from certificate", username); } } bson_init (&cmd); BSON_APPEND_INT32 (&cmd, "authenticate", 1); BSON_APPEND_UTF8 (&cmd, "mechanism", "MONGODB-X509"); BSON_APPEND_UTF8 (&cmd, "user", username); ret = mongoc_cluster_run_command (cluster, stream, 0, MONGOC_QUERY_SLAVE_OK, "$external", &cmd, &reply, error); if (!ret) { /* error->message is already set */ error->domain = MONGOC_ERROR_CLIENT; error->code = MONGOC_ERROR_CLIENT_AUTHENTICATE; } bson_destroy (&cmd); bson_destroy (&reply); return ret; } #endif #ifdef MONGOC_ENABLE_SSL static bool _mongoc_cluster_auth_node_scram (mongoc_cluster_t *cluster, mongoc_stream_t *stream, bson_error_t *error) { uint32_t buflen = 0; mongoc_scram_t scram; bson_iter_t iter; bool ret = false; const char *tmpstr; const char *auth_source; uint8_t buf[4096] = { 0 }; bson_t cmd; bson_t reply; int conv_id = 0; bson_subtype_t btype; BSON_ASSERT (cluster); BSON_ASSERT (stream); if (!(auth_source = mongoc_uri_get_auth_source(cluster->uri)) || (*auth_source == '\0')) { auth_source = "admin"; } _mongoc_scram_init(&scram); _mongoc_scram_set_pass (&scram, mongoc_uri_get_password (cluster->uri)); _mongoc_scram_set_user (&scram, mongoc_uri_get_username (cluster->uri)); for (;;) { if (!_mongoc_scram_step (&scram, buf, buflen, buf, sizeof buf, &buflen, error)) { goto failure; } bson_init (&cmd); if (scram.step == 1) { BSON_APPEND_INT32 (&cmd, "saslStart", 1); BSON_APPEND_UTF8 (&cmd, "mechanism", "SCRAM-SHA-1"); bson_append_binary (&cmd, "payload", 7, BSON_SUBTYPE_BINARY, buf, buflen); BSON_APPEND_INT32 (&cmd, "autoAuthorize", 1); } else { BSON_APPEND_INT32 (&cmd, "saslContinue", 1); BSON_APPEND_INT32 (&cmd, "conversationId", conv_id); bson_append_binary (&cmd, "payload", 7, BSON_SUBTYPE_BINARY, buf, buflen); } MONGOC_INFO ("SCRAM: authenticating \"%s\" (step %d)", mongoc_uri_get_username (cluster->uri), scram.step); if (!mongoc_cluster_run_command (cluster, stream, 0, MONGOC_QUERY_SLAVE_OK, auth_source, &cmd, &reply, error)) { bson_destroy (&cmd); bson_destroy (&reply); /* error->message is already set */ error->domain = MONGOC_ERROR_CLIENT; error->code = MONGOC_ERROR_CLIENT_AUTHENTICATE; goto failure; } bson_destroy (&cmd); if (bson_iter_init_find (&iter, &reply, "done") && bson_iter_as_bool (&iter)) { bson_destroy (&reply); break; } if (!bson_iter_init_find (&iter, &reply, "conversationId") || !BSON_ITER_HOLDS_INT32 (&iter) || !(conv_id = bson_iter_int32 (&iter)) || !bson_iter_init_find (&iter, &reply, "payload") || !BSON_ITER_HOLDS_BINARY(&iter)) { const char *errmsg = "Received invalid SCRAM reply from MongoDB server."; MONGOC_INFO ("SCRAM: authentication failed for \"%s\"", mongoc_uri_get_username (cluster->uri)); if (bson_iter_init_find (&iter, &reply, "errmsg") && BSON_ITER_HOLDS_UTF8 (&iter)) { errmsg = bson_iter_utf8 (&iter, NULL); } bson_set_error (error, MONGOC_ERROR_CLIENT, MONGOC_ERROR_CLIENT_AUTHENTICATE, "%s", errmsg); bson_destroy (&reply); goto failure; } bson_iter_binary (&iter, &btype, &buflen, (const uint8_t**)&tmpstr); if (buflen > sizeof buf) { bson_set_error (error, MONGOC_ERROR_CLIENT, MONGOC_ERROR_CLIENT_AUTHENTICATE, "SCRAM reply from MongoDB is too large."); bson_destroy (&reply); goto failure; } memcpy (buf, tmpstr, buflen); bson_destroy (&reply); } MONGOC_INFO ("SCRAM: \"%s\" authenticated", mongoc_uri_get_username (cluster->uri)); ret = true; failure: _mongoc_scram_destroy (&scram); return ret; } #endif /* *-------------------------------------------------------------------------- * * _mongoc_cluster_auth_node -- * * Authenticate a cluster node depending on the required mechanism. * * Returns: * true if authenticated. false on failure and @error is set. * * Side effects: * @error is set on failure. * *-------------------------------------------------------------------------- */ static bool _mongoc_cluster_auth_node (mongoc_cluster_t *cluster, mongoc_stream_t *stream, const char *hostname, int32_t max_wire_version, bson_error_t *error) { bool ret = false; const char *mechanism; ENTRY; BSON_ASSERT (cluster); BSON_ASSERT (stream); mechanism = mongoc_uri_get_auth_mechanism (cluster->uri); /* Use cached max_wire_version, not value from sd */ if (!mechanism) { if (max_wire_version < WIRE_VERSION_SCRAM_DEFAULT) { mechanism = "MONGODB-CR"; } else { mechanism = "SCRAM-SHA-1"; } } if (0 == strcasecmp (mechanism, "MONGODB-CR")) { ret = _mongoc_cluster_auth_node_cr (cluster, stream, error); } else if (0 == strcasecmp (mechanism, "MONGODB-X509")) { #ifdef MONGOC_ENABLE_SSL ret = _mongoc_cluster_auth_node_x509 (cluster, stream, error); #else bson_set_error (error, MONGOC_ERROR_CLIENT, MONGOC_ERROR_CLIENT_AUTHENTICATE, "The \"%s\" authentication mechanism requires libmongoc built with --enable-ssl", mechanism); #endif } else if (0 == strcasecmp (mechanism, "SCRAM-SHA-1")) { #ifdef MONGOC_ENABLE_SSL ret = _mongoc_cluster_auth_node_scram (cluster, stream, error); #else bson_set_error (error, MONGOC_ERROR_CLIENT, MONGOC_ERROR_CLIENT_AUTHENTICATE, "The \"%s\" authentication mechanism requires libmongoc built with --enable-ssl", mechanism); #endif } else if (0 == strcasecmp (mechanism, "GSSAPI")) { #ifdef MONGOC_ENABLE_SASL ret = _mongoc_cluster_auth_node_sasl (cluster, stream, hostname, error); #else bson_set_error (error, MONGOC_ERROR_CLIENT, MONGOC_ERROR_CLIENT_AUTHENTICATE, "The \"%s\" authentication mechanism requires libmongoc built with --enable-sasl", mechanism); #endif } else if (0 == strcasecmp (mechanism, "PLAIN")) { ret = _mongoc_cluster_auth_node_plain (cluster, stream, error); } else { bson_set_error (error, MONGOC_ERROR_CLIENT, MONGOC_ERROR_CLIENT_AUTHENTICATE, "Unknown authentication mechanism \"%s\".", mechanism); } if (!ret) { mongoc_counter_auth_failure_inc (); MONGOC_DEBUG("Authentication failed: %s", error->message); } else { mongoc_counter_auth_success_inc (); TRACE("%s", "Authentication succeeded"); } RETURN(ret); } /* *-------------------------------------------------------------------------- * * mongoc_cluster_disconnect_node -- * * Remove a node from the set of nodes. This should be done if * a stream in the set is found to be invalid. * * WARNING: pointers to a disconnected mongoc_cluster_node_t or * its stream are now invalid, be careful of dangling pointers. * * Returns: * None. * * Side effects: * Removes node from cluster's set of nodes, and frees the * mongoc_cluster_node_t if pooled. * *-------------------------------------------------------------------------- */ void mongoc_cluster_disconnect_node (mongoc_cluster_t *cluster, uint32_t server_id) { mongoc_topology_t *topology = cluster->client->topology; ENTRY; if (topology->single_threaded) { mongoc_topology_scanner_node_t *scanner_node; scanner_node = mongoc_topology_scanner_get_node (topology->scanner, server_id); /* might never actually have connected */ if (scanner_node && scanner_node->stream) { mongoc_topology_scanner_node_disconnect (scanner_node, true); EXIT; } EXIT; } else { mongoc_set_rm(cluster->nodes, server_id); } EXIT; } static void _mongoc_cluster_node_destroy (mongoc_cluster_node_t *node) { /* Failure, or Replica Set reconfigure without this node */ mongoc_stream_failed (node->stream); bson_free (node); } static void _mongoc_cluster_node_dtor (void *data_, void *ctx_) { mongoc_cluster_node_t *node = (mongoc_cluster_node_t *)data_; _mongoc_cluster_node_destroy (node); } static mongoc_cluster_node_t * _mongoc_cluster_node_new (mongoc_stream_t *stream) { mongoc_cluster_node_t *node; if (!stream) { return NULL; } node = (mongoc_cluster_node_t *)bson_malloc0(sizeof *node); node->stream = stream; node->timestamp = bson_get_monotonic_time (); node->max_wire_version = MONGOC_DEFAULT_WIRE_VERSION; node->min_wire_version = MONGOC_DEFAULT_WIRE_VERSION; node->max_write_batch_size = MONGOC_DEFAULT_WRITE_BATCH_SIZE; node->max_bson_obj_size = MONGOC_DEFAULT_BSON_OBJ_SIZE; node->max_msg_size = MONGOC_DEFAULT_MAX_MSG_SIZE; return node; } /* *-------------------------------------------------------------------------- * * mongoc_cluster_add_node -- * * Add a new node to this cluster for the given server description. * * NOTE: does NOT check if this server is already in the cluster. * * Returns: * A stream connected to the server, or NULL on failure. * * Side effects: * Adds a cluster node, or sets error on failure. * *-------------------------------------------------------------------------- */ static mongoc_stream_t * _mongoc_cluster_add_node (mongoc_cluster_t *cluster, mongoc_server_description_t *sd, bson_error_t *error /* OUT */) { mongoc_cluster_node_t *cluster_node; mongoc_stream_t *stream; ENTRY; BSON_ASSERT (cluster); BSON_ASSERT (!cluster->client->topology->single_threaded); TRACE ("Adding new server to cluster: %s", sd->connection_address); stream = _mongoc_client_create_stream(cluster->client, &sd->host, error); if (!stream) { MONGOC_WARNING ("Failed connection to %s (%s)", sd->connection_address, error->message); RETURN (NULL); } /* take critical fields from a fresh ismaster */ cluster_node = _mongoc_cluster_node_new (stream); if (!_mongoc_cluster_run_ismaster (cluster, cluster_node)) { _mongoc_cluster_node_destroy (cluster_node); MONGOC_WARNING ("Failed connection to %s (ismaster failed)", sd->connection_address); RETURN (NULL); } if (cluster->requires_auth) { if (!_mongoc_cluster_auth_node (cluster, cluster_node->stream, sd->host.host, cluster_node->max_wire_version, error)) { MONGOC_WARNING ("Failed authentication to %s (%s)", sd->connection_address, error->message); _mongoc_cluster_node_destroy (cluster_node); RETURN (NULL); } } mongoc_set_add (cluster->nodes, sd->id, cluster_node); RETURN (stream); } static void node_not_found (mongoc_server_description_t *sd, bson_error_t *error /* OUT */) { if (sd->error.code) { memcpy (error, &sd->error, sizeof *error); } else { bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_NOT_ESTABLISHED, "Could not find node %s", sd->host.host_and_port); } } static void stream_not_found (mongoc_server_description_t *sd, bson_error_t *error /* OUT */) { if (sd->error.code) { memcpy (error, &sd->error, sizeof *error); } else { bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_NOT_ESTABLISHED, "Could not find stream for node %s", sd->host.host_and_port); } } static mongoc_server_stream_t * _mongoc_cluster_stream_for_server_description (mongoc_cluster_t *cluster, mongoc_server_description_t *sd, bool reconnect_ok, bson_error_t *error) { mongoc_topology_t *topology; mongoc_server_stream_t *server_stream; ENTRY; topology = cluster->client->topology; /* in the single-threaded use case we share topology's streams */ if (topology->single_threaded) { server_stream = mongoc_cluster_fetch_stream_single (cluster, sd, reconnect_ok, error); } else { server_stream = mongoc_cluster_fetch_stream_pooled (cluster, sd, reconnect_ok, error); } if (!server_stream) { /* failed */ mongoc_cluster_disconnect_node (cluster, sd->id); } RETURN (server_stream); } /* *-------------------------------------------------------------------------- * * mongoc_cluster_stream_for_server -- * * Fetch the stream for @server_id. If @reconnect_ok and there is no * valid stream, attempts to reconnect; if not @reconnect_ok then only * an existing stream can be returned, or NULL. * * Returns: * A mongoc_server_stream_t, or NULL * * Side effects: * May add a node or reconnect one, if @reconnect_ok. * Authenticates the stream if needed. * May set @error. * *-------------------------------------------------------------------------- */ mongoc_server_stream_t * mongoc_cluster_stream_for_server (mongoc_cluster_t *cluster, uint32_t server_id, bool reconnect_ok, bson_error_t *error) { mongoc_topology_t *topology; mongoc_server_description_t *sd; mongoc_server_stream_t *server_stream = NULL; ENTRY; BSON_ASSERT (cluster); BSON_ASSERT (server_id); topology = cluster->client->topology; if (!(sd = mongoc_topology_server_by_id (topology, server_id, error))) { RETURN (NULL); } server_stream = _mongoc_cluster_stream_for_server_description (cluster, sd, reconnect_ok, error); if (!server_stream) { /* failed */ mongoc_cluster_disconnect_node (cluster, server_id); mongoc_server_description_destroy (sd); } RETURN (server_stream); } static mongoc_server_stream_t * mongoc_cluster_fetch_stream_single (mongoc_cluster_t *cluster, mongoc_server_description_t *sd, bool reconnect_ok, bson_error_t *error) { mongoc_topology_t *topology; mongoc_stream_t *stream; mongoc_topology_scanner_node_t *scanner_node; int64_t expire_at; bson_t reply; topology = cluster->client->topology; scanner_node = mongoc_topology_scanner_get_node (topology->scanner, sd->id); BSON_ASSERT (scanner_node && !scanner_node->retired); stream = scanner_node->stream; if (!stream) { if (!reconnect_ok) { stream_not_found (sd, error); return NULL; } if (!mongoc_topology_scanner_node_setup (scanner_node, error)) { return NULL; } stream = scanner_node->stream; expire_at = bson_get_monotonic_time() + topology->connect_timeout_msec * 1000; if (!mongoc_stream_wait (stream, expire_at)) { bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_CONNECT, "Failed to connect to target host: '%s'", sd->host.host_and_port); memcpy (&sd->error, error, sizeof sd->error); mongoc_topology_scanner_node_disconnect (scanner_node, true); return NULL; } if (!_mongoc_stream_run_ismaster (cluster, stream, &reply, error)) { mongoc_topology_scanner_node_disconnect (scanner_node, true); return NULL; } /* TODO: run ismaster through the topology machinery? */ bson_destroy (&reply); } /* if stream exists but isn't authed, a disconnect happened */ if (cluster->requires_auth && !scanner_node->has_auth) { /* In single-threaded mode, we can use sd's max_wire_version */ if (!_mongoc_cluster_auth_node (cluster, stream, sd->host.host, sd->max_wire_version, &sd->error)) { memcpy (error, &sd->error, sizeof *error); return NULL; } scanner_node->has_auth = true; } return mongoc_server_stream_new (topology->description.type, sd, stream); } static mongoc_server_stream_t * mongoc_cluster_fetch_stream_pooled (mongoc_cluster_t *cluster, mongoc_server_description_t *sd, bool reconnect_ok, bson_error_t *error) { mongoc_topology_t *topology; mongoc_stream_t *stream; mongoc_cluster_node_t *cluster_node; int64_t timestamp; cluster_node = (mongoc_cluster_node_t *) mongoc_set_get (cluster->nodes, sd->id); topology = cluster->client->topology; if (cluster_node) { BSON_ASSERT (cluster_node->stream); /* existing cluster node, is it outdated? */ timestamp = mongoc_topology_server_timestamp (topology, sd->id); if (timestamp == -1 || cluster_node->timestamp < timestamp) { mongoc_cluster_disconnect_node (cluster, sd->id); } else { /* TODO: thread safety! */ return mongoc_server_stream_new (topology->description.type, sd, cluster_node->stream); } } /* no node, or out of date */ if (!reconnect_ok) { node_not_found (sd, error); return NULL; } stream = _mongoc_cluster_add_node (cluster, sd, error); if (stream) { /* TODO: thread safety! */ return mongoc_server_stream_new (topology->description.type, sd, stream); } else { return NULL; } } /* *-------------------------------------------------------------------------- * * mongoc_cluster_init -- * * Initializes @cluster using the @uri and @client provided. The * @uri is used to determine the "mode" of the cluster. Based on the * uri we can determine if we are connected to a single host, a * replicaSet, or a shardedCluster. * * Returns: * None. * * Side effects: * @cluster is initialized. * *-------------------------------------------------------------------------- */ void mongoc_cluster_init (mongoc_cluster_t *cluster, const mongoc_uri_t *uri, void *client) { ENTRY; BSON_ASSERT (cluster); BSON_ASSERT (uri); memset (cluster, 0, sizeof *cluster); cluster->uri = mongoc_uri_copy(uri); cluster->client = (mongoc_client_t *)client; cluster->requires_auth = (mongoc_uri_get_username(uri) || mongoc_uri_get_auth_mechanism(uri)); cluster->sockettimeoutms = mongoc_uri_get_option_as_int32( uri, "sockettimeoutms", MONGOC_DEFAULT_SOCKETTIMEOUTMS); cluster->socketcheckintervalms = mongoc_uri_get_option_as_int32( uri, "socketcheckintervalms", MONGOC_TOPOLOGY_SOCKET_CHECK_INTERVAL_MS); /* TODO for single-threaded case we don't need this */ cluster->nodes = mongoc_set_new(8, _mongoc_cluster_node_dtor, NULL); _mongoc_array_init (&cluster->iov, sizeof (mongoc_iovec_t)); EXIT; } /* *-------------------------------------------------------------------------- * * mongoc_cluster_destroy -- * * Clean up after @cluster and destroy all active connections. * All resources for @cluster are released. * * Returns: * None. * * Side effects: * Everything. * *-------------------------------------------------------------------------- */ void mongoc_cluster_destroy (mongoc_cluster_t *cluster) /* INOUT */ { ENTRY; BSON_ASSERT (cluster); mongoc_uri_destroy(cluster->uri); mongoc_set_destroy(cluster->nodes); _mongoc_array_destroy(&cluster->iov); EXIT; } /* *-------------------------------------------------------------------------- * * mongoc_cluster_stream_for_optype -- * * Internal server selection. * * Returns: * A mongoc_server_stream_t on which you must call * mongoc_server_stream_cleanup, or NULL on failure (sets @error) * * Side effects: * May set @error. * May add new nodes to @cluster->nodes. * *-------------------------------------------------------------------------- */ static mongoc_server_stream_t * _mongoc_cluster_stream_for_optype (mongoc_cluster_t *cluster, mongoc_ss_optype_t optype, const mongoc_read_prefs_t *read_prefs, bson_error_t *error) { mongoc_server_stream_t *server_stream; mongoc_server_description_t *selected_server; mongoc_topology_t *topology = cluster->client->topology; ENTRY; BSON_ASSERT (cluster); /* this is a new copy of the server description */ selected_server = mongoc_topology_select (topology, optype, read_prefs, 15, error); if (!selected_server) { RETURN(NULL); } /* connect or reconnect to server if necessary */ server_stream = _mongoc_cluster_stream_for_server_description ( cluster, selected_server, true /* reconnect_ok */, error); if (!server_stream ) { mongoc_server_description_destroy (selected_server); RETURN (NULL); } RETURN (server_stream); } /* *-------------------------------------------------------------------------- * * mongoc_cluster_stream_for_reads -- * * Internal server selection. * * Returns: * A mongoc_server_stream_t on which you must call * mongoc_server_stream_cleanup, or NULL on failure (sets @error) * * Side effects: * May set @error. * May add new nodes to @cluster->nodes. * *-------------------------------------------------------------------------- */ mongoc_server_stream_t * mongoc_cluster_stream_for_reads (mongoc_cluster_t *cluster, const mongoc_read_prefs_t *read_prefs, bson_error_t *error) { return _mongoc_cluster_stream_for_optype (cluster, MONGOC_SS_READ, read_prefs, error); } /* *-------------------------------------------------------------------------- * * mongoc_cluster_stream_for_writes -- * * Get a stream for write operations. * * Returns: * A mongoc_server_stream_t on which you must call * mongoc_server_stream_cleanup, or NULL on failure (sets @error) * * Side effects: * May set @error. * May add new nodes to @cluster->nodes. * *-------------------------------------------------------------------------- */ mongoc_server_stream_t * mongoc_cluster_stream_for_writes (mongoc_cluster_t *cluster, bson_error_t *error) { return _mongoc_cluster_stream_for_optype (cluster, MONGOC_SS_WRITE, NULL, error); } /* *-------------------------------------------------------------------------- * * _mongoc_cluster_inc_egress_rpc -- * * Helper to increment the counter for a particular RPC based on * it's opcode. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static BSON_INLINE void _mongoc_cluster_inc_egress_rpc (const mongoc_rpc_t *rpc) { mongoc_counter_op_egress_total_inc(); switch (rpc->header.opcode) { case MONGOC_OPCODE_DELETE: mongoc_counter_op_egress_delete_inc(); break; case MONGOC_OPCODE_UPDATE: mongoc_counter_op_egress_update_inc(); break; case MONGOC_OPCODE_INSERT: mongoc_counter_op_egress_insert_inc(); break; case MONGOC_OPCODE_KILL_CURSORS: mongoc_counter_op_egress_killcursors_inc(); break; case MONGOC_OPCODE_GET_MORE: mongoc_counter_op_egress_getmore_inc(); break; case MONGOC_OPCODE_REPLY: mongoc_counter_op_egress_reply_inc(); break; case MONGOC_OPCODE_MSG: mongoc_counter_op_egress_msg_inc(); break; case MONGOC_OPCODE_QUERY: mongoc_counter_op_egress_query_inc(); break; default: BSON_ASSERT(false); break; } } /* *-------------------------------------------------------------------------- * * _mongoc_cluster_inc_ingress_rpc -- * * Helper to increment the counter for a particular RPC based on * it's opcode. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static BSON_INLINE void _mongoc_cluster_inc_ingress_rpc (const mongoc_rpc_t *rpc) { mongoc_counter_op_ingress_total_inc (); switch (rpc->header.opcode) { case MONGOC_OPCODE_DELETE: mongoc_counter_op_ingress_delete_inc (); break; case MONGOC_OPCODE_UPDATE: mongoc_counter_op_ingress_update_inc (); break; case MONGOC_OPCODE_INSERT: mongoc_counter_op_ingress_insert_inc (); break; case MONGOC_OPCODE_KILL_CURSORS: mongoc_counter_op_ingress_killcursors_inc (); break; case MONGOC_OPCODE_GET_MORE: mongoc_counter_op_ingress_getmore_inc (); break; case MONGOC_OPCODE_REPLY: mongoc_counter_op_ingress_reply_inc (); break; case MONGOC_OPCODE_MSG: mongoc_counter_op_ingress_msg_inc (); break; case MONGOC_OPCODE_QUERY: mongoc_counter_op_ingress_query_inc (); break; default: BSON_ASSERT (false); break; } } static bool _mongoc_cluster_min_of_max_obj_size_sds (void *item, void *ctx) { mongoc_server_description_t *sd = (mongoc_server_description_t *)item; int32_t *current_min = (int32_t *)ctx; if (sd->max_bson_obj_size < *current_min) { *current_min = sd->max_bson_obj_size; } return true; } static bool _mongoc_cluster_min_of_max_obj_size_nodes (void *item, void *ctx) { mongoc_cluster_node_t *node = (mongoc_cluster_node_t *)item; int32_t *current_min = (int32_t *)ctx; if (node->max_bson_obj_size < *current_min) { *current_min = node->max_bson_obj_size; } return true; } static bool _mongoc_cluster_min_of_max_msg_size_sds (void *item, void *ctx) { mongoc_server_description_t *sd = (mongoc_server_description_t *)item; int32_t *current_min = (int32_t *)ctx; if (sd->max_msg_size < *current_min) { *current_min = sd->max_msg_size; } return true; } static bool _mongoc_cluster_min_of_max_msg_size_nodes (void *item, void *ctx) { mongoc_cluster_node_t *node = (mongoc_cluster_node_t *)item; int32_t *current_min = (int32_t *)ctx; if (node->max_msg_size < *current_min) { *current_min = node->max_msg_size; } return true; } /* *-------------------------------------------------------------------------- * * mongoc_cluster_get_max_bson_obj_size -- * * Return the minimum max_bson_obj_size across all servers in cluster. * * NOTE: this method uses the topology's mutex. * * Returns: * The minimum max_bson_obj_size. * * Side effects: * None * *-------------------------------------------------------------------------- */ int32_t mongoc_cluster_get_max_bson_obj_size (mongoc_cluster_t *cluster) { int32_t max_bson_obj_size = -1; max_bson_obj_size = MONGOC_DEFAULT_BSON_OBJ_SIZE; if (!cluster->client->topology->single_threaded) { mongoc_set_for_each (cluster->nodes, _mongoc_cluster_min_of_max_obj_size_nodes, &max_bson_obj_size); } else { mongoc_set_for_each (cluster->client->topology->description.servers, _mongoc_cluster_min_of_max_obj_size_sds, &max_bson_obj_size); } return max_bson_obj_size; } /* *-------------------------------------------------------------------------- * * mongoc_cluster_get_max_msg_size -- * * Return the minimum max msg size across all servers in cluster. * * NOTE: this method uses the topology's mutex. * * Returns: * The minimum max_msg_size * * Side effects: * None * *-------------------------------------------------------------------------- */ int32_t mongoc_cluster_get_max_msg_size (mongoc_cluster_t *cluster) { int32_t max_msg_size = MONGOC_DEFAULT_MAX_MSG_SIZE; if (!cluster->client->topology->single_threaded) { mongoc_set_for_each (cluster->nodes, _mongoc_cluster_min_of_max_msg_size_nodes, &max_msg_size); } else { mongoc_set_for_each (cluster->client->topology->description.servers, _mongoc_cluster_min_of_max_msg_size_sds, &max_msg_size); } return max_msg_size; } /* *-------------------------------------------------------------------------- * * mongoc_cluster_node_min_wire_version -- * * Return the min wire version for the given server. * * Returns: * Min wire version, or -1 if server is not found. * *-------------------------------------------------------------------------- */ int32_t mongoc_cluster_node_min_wire_version (mongoc_cluster_t *cluster, uint32_t server_id) { mongoc_server_description_t *sd; mongoc_cluster_node_t *node; if (cluster->client->topology->single_threaded) { if ((sd = mongoc_topology_description_server_by_id ( &cluster->client->topology->description, server_id, NULL))) { return sd->min_wire_version; } } else { if((node = (mongoc_cluster_node_t *)mongoc_set_get(cluster->nodes, server_id))) { return node->min_wire_version; } } return -1; } static bool _mongoc_cluster_check_interval (mongoc_cluster_t *cluster, uint32_t server_id, bson_error_t *error) { mongoc_topology_t *topology; mongoc_topology_scanner_node_t *scanner_node; mongoc_server_description_t *sd; mongoc_stream_t *stream; int64_t now; int64_t before_ismaster; bson_t command; bson_t reply; bool r; topology = cluster->client->topology; if (!topology->single_threaded) { return true; } scanner_node = mongoc_topology_scanner_get_node (topology->scanner, server_id); if (!scanner_node) { return false; } BSON_ASSERT (!scanner_node->retired); stream = scanner_node->stream; if (!stream) { return false; } now = bson_get_monotonic_time (); if (scanner_node->last_used + (1000 * CHECK_CLOSED_DURATION_MSEC) < now) { if (mongoc_stream_check_closed (stream)) { mongoc_cluster_disconnect_node (cluster, server_id); bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, "Stream is closed"); return false; } } if (scanner_node->last_used + (1000 * cluster->socketcheckintervalms) < now) { bson_init (&command); BSON_APPEND_INT32 (&command, "ismaster", 1); before_ismaster = now; r = mongoc_cluster_run_command (cluster, stream, server_id, MONGOC_QUERY_SLAVE_OK, "admin", &command, &reply, error); now = bson_get_monotonic_time (); bson_destroy (&command); if (r) { sd = mongoc_topology_description_server_by_id (&topology->description, server_id, NULL); if (!sd) { bson_destroy (&reply); return false; } mongoc_topology_description_handle_ismaster ( &topology->description, sd, &reply, (now - before_ismaster) / 1000, /* RTT_MS */ error); bson_destroy (&reply); } else { bson_destroy (&reply); return false; } } return true; } /* *-------------------------------------------------------------------------- * * mongoc_cluster_sendv_to_server -- * * Sends the given RPCs to the given server. * * Returns: * True if successful. * * Side effects: * @rpcs may be mutated and should be considered invalid after calling * this method. * * @error may be set. * *-------------------------------------------------------------------------- */ bool mongoc_cluster_sendv_to_server (mongoc_cluster_t *cluster, mongoc_rpc_t *rpcs, size_t rpcs_len, mongoc_server_stream_t *server_stream, const mongoc_write_concern_t *write_concern, bson_error_t *error) { uint32_t server_id; mongoc_iovec_t *iov; mongoc_topology_scanner_node_t *scanner_node; const bson_t *b; mongoc_rpc_t gle; size_t iovcnt; size_t i; bool need_gle; char cmdname[140]; int32_t max_msg_size; ENTRY; BSON_ASSERT (cluster); BSON_ASSERT (rpcs); BSON_ASSERT (rpcs_len); BSON_ASSERT (server_stream); server_id = server_stream->sd->id; if (cluster->client->in_exhaust) { bson_set_error(error, MONGOC_ERROR_CLIENT, MONGOC_ERROR_CLIENT_IN_EXHAUST, "A cursor derived from this client is in exhaust."); RETURN(false); } if (! write_concern) { write_concern = cluster->client->write_concern; } if (!_mongoc_cluster_check_interval (cluster, server_stream->sd->id, error)) { RETURN (false); } _mongoc_array_clear(&cluster->iov); /* * TODO: We can probably remove the need for sendv and just do send since * we support write concerns now. Also, we clobber our getlasterror on * each subsequent mutation. It's okay, since it comes out correct anyway, * just useless work (and technically the request_id changes). */ for (i = 0; i < rpcs_len; i++) { _mongoc_cluster_inc_egress_rpc (&rpcs[i]); rpcs[i].header.request_id = ++cluster->request_id; need_gle = _mongoc_rpc_needs_gle(&rpcs[i], write_concern); _mongoc_rpc_gather (&rpcs[i], &cluster->iov); max_msg_size = mongoc_server_stream_max_msg_size (server_stream); if (rpcs[i].header.msg_len > max_msg_size) { bson_set_error(error, MONGOC_ERROR_CLIENT, MONGOC_ERROR_CLIENT_TOO_BIG, "Attempted to send an RPC larger than the " "max allowed message size. Was %u, allowed %u.", rpcs[i].header.msg_len, max_msg_size); RETURN(false); } if (need_gle) { gle.query.msg_len = 0; gle.query.request_id = ++cluster->request_id; gle.query.response_to = 0; gle.query.opcode = MONGOC_OPCODE_QUERY; gle.query.flags = MONGOC_QUERY_NONE; switch (rpcs[i].header.opcode) { case MONGOC_OPCODE_INSERT: DB_AND_CMD_FROM_COLLECTION(cmdname, rpcs[i].insert.collection); break; case MONGOC_OPCODE_DELETE: DB_AND_CMD_FROM_COLLECTION(cmdname, rpcs[i].delete_.collection); break; case MONGOC_OPCODE_UPDATE: DB_AND_CMD_FROM_COLLECTION(cmdname, rpcs[i].update.collection); break; default: BSON_ASSERT(false); DB_AND_CMD_FROM_COLLECTION(cmdname, "admin.$cmd"); break; } gle.query.collection = cmdname; gle.query.skip = 0; gle.query.n_return = 1; b = _mongoc_write_concern_get_gle((mongoc_write_concern_t *)write_concern); gle.query.query = bson_get_data(b); gle.query.fields = NULL; _mongoc_rpc_gather(&gle, &cluster->iov); _mongoc_rpc_swab_to_le(&gle); } _mongoc_rpc_swab_to_le(&rpcs[i]); } iov = (mongoc_iovec_t *)cluster->iov.data; iovcnt = cluster->iov.len; BSON_ASSERT (cluster->iov.len); if (!_mongoc_stream_writev_full (server_stream->stream, iov, iovcnt, cluster->sockettimeoutms, error)) { RETURN (false); } if (cluster->client->topology->single_threaded) { scanner_node = mongoc_topology_scanner_get_node (cluster->client->topology->scanner, server_id); if (scanner_node) { scanner_node->last_used = bson_get_monotonic_time (); } } RETURN (true); } /* *-------------------------------------------------------------------------- * * mongoc_cluster_try_recv -- * * Tries to receive the next event from the MongoDB server. * The contents are loaded into @buffer and then * scattered into the @rpc structure. @rpc is valid as long as * @buffer contains the contents read into it. * * Callers that can optimize a reuse of @buffer should do so. It * can save many memory allocations. * * Returns: * True if successful. * * Side effects: * @rpc is set on success, @error on failure. * @buffer will be filled with the input data. * *-------------------------------------------------------------------------- */ bool mongoc_cluster_try_recv (mongoc_cluster_t *cluster, mongoc_rpc_t *rpc, mongoc_buffer_t *buffer, mongoc_server_stream_t *server_stream, bson_error_t *error) { uint32_t server_id; int32_t msg_len; int32_t max_msg_size; off_t pos; ENTRY; BSON_ASSERT (cluster); BSON_ASSERT (rpc); BSON_ASSERT (buffer); BSON_ASSERT (server_stream); server_id = server_stream->sd->id; TRACE ("Waiting for reply from server_id \"%u\"", server_id); /* * Buffer the message length to determine how much more to read. */ pos = buffer->len; if (!_mongoc_buffer_append_from_stream (buffer, server_stream->stream, 4, cluster->sockettimeoutms, error)) { MONGOC_DEBUG("Could not read 4 bytes, stream probably closed or timed out"); mongoc_counter_protocol_ingress_error_inc (); mongoc_cluster_disconnect_node(cluster, server_id); RETURN (false); } /* * Read the msg length from the buffer. */ memcpy (&msg_len, &buffer->data[buffer->off + pos], 4); msg_len = BSON_UINT32_FROM_LE (msg_len); max_msg_size = mongoc_server_stream_max_msg_size (server_stream); if ((msg_len < 16) || (msg_len > max_msg_size)) { bson_set_error (error, MONGOC_ERROR_PROTOCOL, MONGOC_ERROR_PROTOCOL_INVALID_REPLY, "Corrupt or malicious reply received."); mongoc_cluster_disconnect_node(cluster, server_id); mongoc_counter_protocol_ingress_error_inc (); RETURN (false); } /* * Read the rest of the message from the stream. */ if (!_mongoc_buffer_append_from_stream (buffer, server_stream->stream, msg_len - 4, cluster->sockettimeoutms, error)) { mongoc_cluster_disconnect_node (cluster, server_id); mongoc_counter_protocol_ingress_error_inc (); RETURN (false); } /* * Scatter the buffer into the rpc structure. */ if (!_mongoc_rpc_scatter (rpc, &buffer->data[buffer->off + pos], msg_len)) { bson_set_error (error, MONGOC_ERROR_PROTOCOL, MONGOC_ERROR_PROTOCOL_INVALID_REPLY, "Failed to decode reply from server."); mongoc_cluster_disconnect_node (cluster, server_id); mongoc_counter_protocol_ingress_error_inc (); RETURN (false); } _mongoc_rpc_swab_from_le (rpc); _mongoc_cluster_inc_ingress_rpc (rpc); RETURN(true); } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-collection-private.h0000664000175000017500000000427512673034026025063 0ustar jmikolajmikola/* * Copyright 2013-2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_COLLECTION_PRIVATE_H #define MONGOC_COLLECTION_PRIVATE_H #if !defined (MONGOC_I_AM_A_DRIVER) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #include #include "mongoc-buffer-private.h" #include "mongoc-client.h" BSON_BEGIN_DECLS struct _mongoc_collection_t { mongoc_client_t *client; char ns[128]; uint32_t nslen; char db[128]; char collection[128]; uint32_t collectionlen; mongoc_buffer_t buffer; mongoc_read_prefs_t *read_prefs; mongoc_read_concern_t *read_concern; mongoc_write_concern_t *write_concern; bson_t *gle; }; mongoc_collection_t *_mongoc_collection_new (mongoc_client_t *client, const char *db, const char *collection, const mongoc_read_prefs_t *read_prefs, const mongoc_read_concern_t *read_concern, const mongoc_write_concern_t *write_concern); mongoc_cursor_t *_mongoc_collection_find_indexes_legacy (mongoc_collection_t *collection, bson_error_t *error); BSON_END_DECLS #endif /* MONGOC_COLLECTION_PRIVATE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-collection.c0000664000175000017500000021124512673034026023403 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include "mongoc-bulk-operation.h" #include "mongoc-bulk-operation-private.h" #include "mongoc-client-private.h" #include "mongoc-find-and-modify-private.h" #include "mongoc-find-and-modify.h" #include "mongoc-collection.h" #include "mongoc-collection-private.h" #include "mongoc-cursor-private.h" #include "mongoc-cursor-cursorid-private.h" #include "mongoc-cursor-array-private.h" #include "mongoc-error.h" #include "mongoc-index.h" #include "mongoc-log.h" #include "mongoc-trace.h" #include "mongoc-read-concern-private.h" #include "mongoc-write-concern-private.h" #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "collection" #define _BSON_APPEND_WRITE_CONCERN(_bson, _write_concern) \ do { \ const bson_t *write_concern_bson; \ mongoc_write_concern_t *write_concern_copy = NULL; \ if (_write_concern->frozen) { \ write_concern_bson = _mongoc_write_concern_get_bson (_write_concern); \ } else { \ /* _mongoc_write_concern_get_bson will freeze the write_concern */ \ write_concern_copy = mongoc_write_concern_copy (_write_concern); \ write_concern_bson = _mongoc_write_concern_get_bson (write_concern_copy); \ } \ BSON_APPEND_DOCUMENT (_bson, "writeConcern", write_concern_bson); \ if (write_concern_copy) { \ mongoc_write_concern_destroy (write_concern_copy); \ } \ } while(0); \ static bool validate_name (const char *str) { const char *c; if (str && *str) { for (c = str; *c; c++) { switch (*c) { case '/': case '\\': case '.': case '"': case '*': case '<': case '>': case ':': case '|': case '?': return false; default: break; } } return ((0 != strcmp (str, "oplog.$main")) && (0 != strcmp (str, "$cmd"))); } return false; } static mongoc_cursor_t * _mongoc_collection_cursor_new (mongoc_collection_t *collection, mongoc_query_flags_t flags) { return _mongoc_cursor_new (collection->client, collection->ns, flags, 0, /* skip */ 0, /* limit */ 0, /* batch_size */ false, /* is_command */ NULL, /* query */ NULL, /* fields */ NULL, /* read prefs */ NULL); /* read concern */ } static void _mongoc_collection_write_command_execute (mongoc_write_command_t *command, const mongoc_collection_t *collection, const mongoc_write_concern_t *write_concern, mongoc_write_result_t *result) { mongoc_server_stream_t *server_stream; ENTRY; server_stream = mongoc_cluster_stream_for_writes (&collection->client->cluster, &result->error); if (!server_stream) { /* result->error has been filled out */ EXIT; } _mongoc_write_command_execute (command, collection->client, server_stream, collection->db, collection->collection, write_concern, 0 /* offset */, result); mongoc_server_stream_cleanup (server_stream); EXIT; } /* *-------------------------------------------------------------------------- * * _mongoc_collection_new -- * * INTERNAL API * * Create a new mongoc_collection_t structure for the given client. * * @client must remain valid during the lifetime of this structure. * @db is the db name of the collection. * @collection is the name of the collection. * @read_prefs is the default read preferences to apply or NULL. * @read_concern is the default read concern to apply or NULL. * @write_concern is the default write concern to apply or NULL. * * Returns: * A newly allocated mongoc_collection_t that should be freed with * mongoc_collection_destroy(). * * Side effects: * None. * *-------------------------------------------------------------------------- */ mongoc_collection_t * _mongoc_collection_new (mongoc_client_t *client, const char *db, const char *collection, const mongoc_read_prefs_t *read_prefs, const mongoc_read_concern_t *read_concern, const mongoc_write_concern_t *write_concern) { mongoc_collection_t *col; ENTRY; BSON_ASSERT (client); BSON_ASSERT (db); BSON_ASSERT (collection); col = (mongoc_collection_t *)bson_malloc0(sizeof *col); col->client = client; col->write_concern = write_concern ? mongoc_write_concern_copy(write_concern) : mongoc_write_concern_new(); col->read_concern = read_concern ? mongoc_read_concern_copy(read_concern) : mongoc_read_concern_new(); col->read_prefs = read_prefs ? mongoc_read_prefs_copy(read_prefs) : mongoc_read_prefs_new(MONGOC_READ_PRIMARY); bson_snprintf (col->ns, sizeof col->ns, "%s.%s", db, collection); bson_snprintf (col->db, sizeof col->db, "%s", db); bson_snprintf (col->collection, sizeof col->collection, "%s", collection); col->collectionlen = (uint32_t)strlen(col->collection); col->nslen = (uint32_t)strlen(col->ns); _mongoc_buffer_init(&col->buffer, NULL, 0, NULL, NULL); col->gle = NULL; RETURN(col); } /* *-------------------------------------------------------------------------- * * mongoc_collection_destroy -- * * Release resources associated with @collection and frees the * structure. * * Returns: * None. * * Side effects: * Everything. * *-------------------------------------------------------------------------- */ void mongoc_collection_destroy (mongoc_collection_t *collection) /* IN */ { ENTRY; BSON_ASSERT (collection); bson_clear (&collection->gle); _mongoc_buffer_destroy(&collection->buffer); if (collection->read_prefs) { mongoc_read_prefs_destroy(collection->read_prefs); collection->read_prefs = NULL; } if (collection->read_concern) { mongoc_read_concern_destroy(collection->read_concern); collection->read_concern = NULL; } if (collection->write_concern) { mongoc_write_concern_destroy(collection->write_concern); collection->write_concern = NULL; } bson_free(collection); EXIT; } /* *-------------------------------------------------------------------------- * * mongoc_collection_copy -- * * Returns a copy of @collection that needs to be freed by calling * mongoc_collection_destroy. * * Returns: * A copy of this collection. * * Side effects: * None. * *-------------------------------------------------------------------------- */ mongoc_collection_t * mongoc_collection_copy (mongoc_collection_t *collection) /* IN */ { ENTRY; BSON_ASSERT (collection); RETURN(_mongoc_collection_new(collection->client, collection->db, collection->collection, collection->read_prefs, collection->read_concern, collection->write_concern)); } /* *-------------------------------------------------------------------------- * * mongoc_collection_aggregate -- * * Send an "aggregate" command to the MongoDB server. * * This varies it's behavior based on the wire version. If we're on * wire_version > 0, we use the new aggregate command, which returns a * database cursor. On wire_version == 0, we create synthetic cursor on * top of the array returned in result. * * This function will always return a new mongoc_cursor_t that should * be freed with mongoc_cursor_destroy(). * * The cursor may fail once iterated upon, so check * mongoc_cursor_error() if mongoc_cursor_next() returns false. * * See http://docs.mongodb.org/manual/aggregation/ for more * information on how to build aggregation pipelines. * * Requires: * MongoDB >= 2.1.0 * * Parameters: * @flags: bitwise or of mongoc_query_flags_t or 0. * @pipeline: A bson_t containing the pipeline request. @pipeline * will be sent as an array type in the request. * @options: A bson_t containing aggregation options, such as * bypassDocumentValidation (used with $out pipeline), * maxTimeMS (declaring maximum server execution time) and * explain (return information on the processing of the pipeline). * @read_prefs: Optional read preferences for the command. * * Returns: * A newly allocated mongoc_cursor_t that should be freed with * mongoc_cursor_destroy(). * * Side effects: * None. * *-------------------------------------------------------------------------- */ mongoc_cursor_t * mongoc_collection_aggregate (mongoc_collection_t *collection, /* IN */ mongoc_query_flags_t flags, /* IN */ const bson_t *pipeline, /* IN */ const bson_t *options, /* IN */ const mongoc_read_prefs_t *read_prefs) /* IN */ { mongoc_server_description_t *selected_server; mongoc_cursor_t *cursor; bson_iter_t iter; bson_t command; bson_t child; int32_t batch_size = 0; bool use_cursor; ENTRY; BSON_ASSERT (collection); BSON_ASSERT (pipeline); bson_init (&command); if (!read_prefs) { read_prefs = collection->read_prefs; } cursor = _mongoc_collection_cursor_new (collection, flags); selected_server = mongoc_topology_select(collection->client->topology, MONGOC_SS_READ, read_prefs, 15, &cursor->error); if (!selected_server) { GOTO (done); } cursor->hint = selected_server->id; use_cursor = selected_server->max_wire_version >= WIRE_VERSION_AGG_CURSOR; BSON_APPEND_UTF8 (&command, "aggregate", collection->collection); /* * The following will allow @pipeline to be either an array of * items for the pipeline, or {"pipeline": [...]}. */ if (bson_iter_init_find (&iter, pipeline, "pipeline") && BSON_ITER_HOLDS_ARRAY (&iter)) { if (!bson_append_iter (&command, "pipeline", 8, &iter)) { bson_set_error (&cursor->error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "Failed to append \"pipeline\" to create command."); GOTO (done); } } else { BSON_APPEND_ARRAY (&command, "pipeline", pipeline); } /* for newer version, we include a cursor subdocument */ if (use_cursor) { bson_append_document_begin (&command, "cursor", 6, &child); if (options && bson_iter_init (&iter, options)) { while (bson_iter_next (&iter)) { if (BSON_ITER_IS_KEY (&iter, "batchSize") && (BSON_ITER_HOLDS_INT32 (&iter) || BSON_ITER_HOLDS_INT64 (&iter) || BSON_ITER_HOLDS_DOUBLE (&iter))) { batch_size = (int32_t)bson_iter_as_int64 (&iter); BSON_APPEND_INT32 (&child, "batchSize", batch_size); } } } bson_append_document_end (&command, &child); } if (options && bson_iter_init (&iter, options)) { while (bson_iter_next (&iter)) { if (! (BSON_ITER_IS_KEY (&iter, "batchSize") || BSON_ITER_IS_KEY (&iter, "cursor"))) { if (!bson_append_iter (&command, bson_iter_key (&iter), -1, &iter)) { bson_set_error (&cursor->error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "Failed to append \"batchSize\" or \"cursor\" to create command."); GOTO (done); } } } } if (collection->read_concern->level != NULL) { const bson_t *read_concern_bson; if (selected_server->max_wire_version < WIRE_VERSION_READ_CONCERN) { bson_set_error (&cursor->error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, "The selected server does not support readConcern"); GOTO (done); } read_concern_bson = _mongoc_read_concern_get_bson (collection->read_concern); BSON_APPEND_DOCUMENT (&command, "readConcern", read_concern_bson); } if (use_cursor) { _mongoc_cursor_cursorid_init (cursor, &command); } else { /* for older versions we get an array that we can create a synthetic * cursor on top of */ _mongoc_cursor_array_init (cursor, &command, "result"); } done: if (selected_server) { mongoc_server_description_destroy (selected_server); } bson_destroy(&command); /* we always return the cursor, even if it fails; users can detect the * failure on performing a cursor operation. see CDRIVER-880. */ RETURN (cursor); } /* *-------------------------------------------------------------------------- * * mongoc_collection_find -- * * Performs a query against the configured MongoDB server. If @read_prefs * is provided, it will be used to locate a MongoDB node in the cluster * to deliver the query to. * * @flags may be bitwise-or'd flags or MONGOC_QUERY_NONE. * * @skip may contain the number of documents to skip before returning the * matching document. * * @limit may contain the maximum number of documents that may be * returned. * * This function will always return a cursor, with the exception of * invalid API use. * * Parameters: * @collection: A mongoc_collection_t. * @flags: A bitwise or of mongoc_query_flags_t. * @skip: The number of documents to skip. * @limit: The maximum number of items. * @batch_size: The batch size * @query: The query to locate matching documents. * @fields: The fields to return, or NULL for all fields. * @read_prefs: Read preferences to choose cluster node. * * Returns: * A newly allocated mongoc_cursor_t that should be freed with * mongoc_cursor_destroy(). * * The client used by mongoc_collection_t must be valid for the * lifetime of the resulting mongoc_cursor_t. * * Side effects: * None. * *-------------------------------------------------------------------------- */ mongoc_cursor_t * mongoc_collection_find (mongoc_collection_t *collection, /* IN */ mongoc_query_flags_t flags, /* IN */ uint32_t skip, /* IN */ uint32_t limit, /* IN */ uint32_t batch_size, /* IN */ const bson_t *query, /* IN */ const bson_t *fields, /* IN */ const mongoc_read_prefs_t *read_prefs) /* IN */ { BSON_ASSERT (collection); BSON_ASSERT (query); bson_clear (&collection->gle); if (!read_prefs) { read_prefs = collection->read_prefs; } return _mongoc_cursor_new (collection->client, collection->ns, flags, skip, limit, batch_size, false, query, fields, read_prefs, collection->read_concern); } /* *-------------------------------------------------------------------------- * * mongoc_collection_command -- * * Executes a command on a cluster node matching @read_prefs. If * @read_prefs is not provided, it will be run on the primary node. * * This function will always return a mongoc_cursor_t. * * Parameters: * @collection: A mongoc_collection_t. * @flags: Bitwise-or'd flags for command. * @skip: Number of documents to skip, typically 0. * @limit : Number of documents to return * @batch_size : Batch size * @query: The command to execute. * @fields: The fields to return, or NULL. * @read_prefs: Command read preferences or NULL. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ mongoc_cursor_t * mongoc_collection_command (mongoc_collection_t *collection, mongoc_query_flags_t flags, uint32_t skip, uint32_t limit, uint32_t batch_size, const bson_t *query, const bson_t *fields, const mongoc_read_prefs_t *read_prefs) { char ns[MONGOC_NAMESPACE_MAX]; BSON_ASSERT (collection); BSON_ASSERT (query); if (!read_prefs) { read_prefs = collection->read_prefs; } bson_clear (&collection->gle); if (NULL == strstr (collection->collection, "$cmd")) { bson_snprintf (ns, sizeof ns, "%s", collection->db); } else { bson_snprintf (ns, sizeof ns, "%s.%s", collection->db, collection->collection); } return mongoc_client_command (collection->client, ns, flags, skip, limit, batch_size, query, fields, read_prefs); } bool mongoc_collection_command_simple (mongoc_collection_t *collection, const bson_t *command, const mongoc_read_prefs_t *read_prefs, bson_t *reply, bson_error_t *error) { BSON_ASSERT (collection); BSON_ASSERT (command); bson_clear (&collection->gle); return mongoc_client_command_simple (collection->client, collection->db, command, read_prefs, reply, error); } /* *-------------------------------------------------------------------------- * * mongoc_collection_count -- * * Count the number of documents matching @query. * * Parameters: * @flags: A mongoc_query_flags_t describing the query flags or 0. * @query: The query to perform or NULL for {}. * @skip: The $skip to perform within the query or 0. * @limit: The $limit to perform within the query or 0. * @read_prefs: desired read preferences or NULL. * @error: A location for an error or NULL. * * Returns: * -1 on failure; otherwise the number of matching documents. * * Side effects: * @error is set upon failure if non-NULL. * *-------------------------------------------------------------------------- */ int64_t mongoc_collection_count (mongoc_collection_t *collection, /* IN */ mongoc_query_flags_t flags, /* IN */ const bson_t *query, /* IN */ int64_t skip, /* IN */ int64_t limit, /* IN */ const mongoc_read_prefs_t *read_prefs, /* IN */ bson_error_t *error) /* OUT */ { return mongoc_collection_count_with_opts ( collection, flags, query, skip, limit, NULL, read_prefs, error); } int64_t mongoc_collection_count_with_opts (mongoc_collection_t *collection, /* IN */ mongoc_query_flags_t flags, /* IN */ const bson_t *query, /* IN */ int64_t skip, /* IN */ int64_t limit, /* IN */ const bson_t *opts, /* IN */ const mongoc_read_prefs_t *read_prefs, /* IN */ bson_error_t *error) /* OUT */ { mongoc_server_stream_t *server_stream; mongoc_cluster_t *cluster; bson_iter_t iter; int64_t ret = -1; bool success; bson_t reply; bson_t cmd; bson_t q; ENTRY; cluster = &collection->client->cluster; server_stream = mongoc_cluster_stream_for_writes (cluster, error); if (!server_stream) { RETURN (-1); } BSON_ASSERT (collection); bson_init(&cmd); bson_append_utf8(&cmd, "count", 5, collection->collection, collection->collectionlen); if (query) { bson_append_document(&cmd, "query", 5, query); } else { bson_init(&q); bson_append_document(&cmd, "query", 5, &q); bson_destroy(&q); } if (limit) { bson_append_int64(&cmd, "limit", 5, limit); } if (skip) { bson_append_int64(&cmd, "skip", 4, skip); } if (collection->read_concern->level != NULL) { const bson_t *read_concern_bson; if (server_stream->sd->max_wire_version < WIRE_VERSION_READ_CONCERN) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, "The selected server does not support readConcern"); bson_destroy (&cmd); mongoc_server_stream_cleanup (server_stream); RETURN (-1); } read_concern_bson = _mongoc_read_concern_get_bson (collection->read_concern); BSON_APPEND_DOCUMENT (&cmd, "readConcern", read_concern_bson); } if (opts) { bson_concat(&cmd, opts); } success = mongoc_cluster_run_command (cluster, server_stream->stream, server_stream->sd->id, MONGOC_QUERY_SLAVE_OK, collection->db, &cmd, &reply, error); if (success && bson_iter_init_find(&iter, &reply, "n")) { ret = bson_iter_as_int64(&iter); } bson_destroy (&reply); bson_destroy (&cmd); mongoc_server_stream_cleanup (server_stream); RETURN (ret); } /* *-------------------------------------------------------------------------- * * mongoc_collection_drop -- * * Request the MongoDB server drop the collection. * * Returns: * true if successful; otherwise false and @error is set. * * Side effects: * @error is set upon failure. * *-------------------------------------------------------------------------- */ bool mongoc_collection_drop (mongoc_collection_t *collection, /* IN */ bson_error_t *error) /* OUT */ { bool ret; bson_t cmd; BSON_ASSERT (collection); bson_init(&cmd); bson_append_utf8(&cmd, "drop", 4, collection->collection, collection->collectionlen); ret = mongoc_collection_command_simple(collection, &cmd, NULL, NULL, error); bson_destroy(&cmd); return ret; } /* *-------------------------------------------------------------------------- * * mongoc_collection_drop_index -- * * Request the MongoDB server drop the named index. * * Returns: * true if successful; otherwise false and @error is set. * * Side effects: * @error is setup upon failure if non-NULL. * *-------------------------------------------------------------------------- */ bool mongoc_collection_drop_index (mongoc_collection_t *collection, /* IN */ const char *index_name, /* IN */ bson_error_t *error) /* OUT */ { bool ret; bson_t cmd; BSON_ASSERT (collection); BSON_ASSERT (index_name); bson_init(&cmd); bson_append_utf8(&cmd, "dropIndexes", -1, collection->collection, collection->collectionlen); bson_append_utf8(&cmd, "index", -1, index_name, -1); ret = mongoc_collection_command_simple(collection, &cmd, NULL, NULL, error); bson_destroy(&cmd); return ret; } char * mongoc_collection_keys_to_index_string (const bson_t *keys) { bson_string_t *s; bson_iter_t iter; int i = 0; BSON_ASSERT (keys); if (!bson_iter_init (&iter, keys)) { return NULL; } s = bson_string_new (NULL); while (bson_iter_next (&iter)) { /* Index type can be specified as a string ("2d") or as an integer representing direction */ if (bson_iter_type(&iter) == BSON_TYPE_UTF8) { bson_string_append_printf (s, (i++ ? "_%s_%s" : "%s_%s"), bson_iter_key (&iter), bson_iter_utf8 (&iter, NULL)); } else { bson_string_append_printf (s, (i++ ? "_%s_%d" : "%s_%d"), bson_iter_key (&iter), bson_iter_int32 (&iter)); } } return bson_string_free (s, false); } /* *-------------------------------------------------------------------------- * * _mongoc_collection_create_index_legacy -- * * Request the MongoDB server create the named index. * * Returns: * true if successful; otherwise false and @error is set. * * Side effects: * @error is setup upon failure if non-NULL. * *-------------------------------------------------------------------------- */ static bool _mongoc_collection_create_index_legacy (mongoc_collection_t *collection, const bson_t *keys, const mongoc_index_opt_t *opt, bson_error_t *error) { const mongoc_index_opt_t *def_opt; mongoc_collection_t *col; bool ret; bson_t insert; char *name; BSON_ASSERT (collection); /* * TODO: this is supposed to be cached and cheap... make it that way */ def_opt = mongoc_index_opt_get_default (); opt = opt ? opt : def_opt; if (!opt->is_initialized) { MONGOC_WARNING("Options have not yet been initialized"); return false; } bson_init (&insert); bson_append_document (&insert, "key", -1, keys); bson_append_utf8 (&insert, "ns", -1, collection->ns, -1); if (opt->background != def_opt->background) { bson_append_bool (&insert, "background", -1, opt->background); } if (opt->unique != def_opt->unique) { bson_append_bool (&insert, "unique", -1, opt->unique); } if (opt->name != def_opt->name) { bson_append_utf8 (&insert, "name", -1, opt->name, -1); } else { name = mongoc_collection_keys_to_index_string(keys); if (!name) { bson_set_error (error, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, "Cannot generate index name from invalid `keys` argument" ); bson_destroy (&insert); return false; } bson_append_utf8 (&insert, "name", -1, name, -1); bson_free (name); } if (opt->drop_dups != def_opt->drop_dups) { bson_append_bool (&insert, "dropDups", -1, opt->drop_dups); } if (opt->sparse != def_opt->sparse) { bson_append_bool (&insert, "sparse", -1, opt->sparse); } if (opt->expire_after_seconds != def_opt->expire_after_seconds) { bson_append_int32 (&insert, "expireAfterSeconds", -1, opt->expire_after_seconds); } if (opt->v != def_opt->v) { bson_append_int32 (&insert, "v", -1, opt->v); } if (opt->weights != def_opt->weights) { bson_append_document (&insert, "weights", -1, opt->weights); } if (opt->default_language != def_opt->default_language) { bson_append_utf8 (&insert, "default_language", -1, opt->default_language, -1); } if (opt->language_override != def_opt->language_override) { bson_append_utf8 (&insert, "language_override", -1, opt->language_override, -1); } col = mongoc_client_get_collection (collection->client, collection->db, "system.indexes"); ret = mongoc_collection_insert (col, (mongoc_insert_flags_t)MONGOC_INSERT_NO_VALIDATE, &insert, NULL, error); mongoc_collection_destroy(col); bson_destroy (&insert); return ret; } bool mongoc_collection_create_index (mongoc_collection_t *collection, const bson_t *keys, const mongoc_index_opt_t *opt, bson_error_t *error) { const mongoc_index_opt_t *def_opt; const mongoc_index_opt_geo_t *def_geo; bson_error_t local_error; const char *name; bson_t cmd = BSON_INITIALIZER; bson_t ar; bson_t doc; bson_t reply; bson_t storage_doc; bson_t wt_doc; const mongoc_index_opt_geo_t *geo_opt; const mongoc_index_opt_storage_t *storage_opt; const mongoc_index_opt_wt_t *wt_opt; char *alloc_name = NULL; bool ret = false; BSON_ASSERT (collection); BSON_ASSERT (keys); def_opt = mongoc_index_opt_get_default (); opt = opt ? opt : def_opt; /* * Generate the key name if it was not provided. */ name = (opt->name != def_opt->name) ? opt->name : NULL; if (!name) { alloc_name = mongoc_collection_keys_to_index_string (keys); if (alloc_name) { name = alloc_name; } else { bson_set_error (error, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, "Cannot generate index name from invalid `keys` argument" ); bson_destroy (&cmd); return false; } } /* * Build our createIndexes command to send to the server. */ BSON_APPEND_UTF8 (&cmd, "createIndexes", collection->collection); bson_append_array_begin (&cmd, "indexes", 7, &ar); bson_append_document_begin (&ar, "0", 1, &doc); BSON_APPEND_DOCUMENT (&doc, "key", keys); BSON_APPEND_UTF8 (&doc, "name", name); if (opt->background) { BSON_APPEND_BOOL (&doc, "background", true); } if (opt->unique) { BSON_APPEND_BOOL (&doc, "unique", true); } if (opt->drop_dups) { BSON_APPEND_BOOL (&doc, "dropDups", true); } if (opt->sparse) { BSON_APPEND_BOOL (&doc, "sparse", true); } if (opt->expire_after_seconds != def_opt->expire_after_seconds) { BSON_APPEND_INT32 (&doc, "expireAfterSeconds", opt->expire_after_seconds); } if (opt->v != def_opt->v) { BSON_APPEND_INT32 (&doc, "v", opt->v); } if (opt->weights && (opt->weights != def_opt->weights)) { BSON_APPEND_DOCUMENT (&doc, "weights", opt->weights); } if (opt->default_language != def_opt->default_language) { BSON_APPEND_UTF8 (&doc, "default_language", opt->default_language); } if (opt->language_override != def_opt->language_override) { BSON_APPEND_UTF8 (&doc, "language_override", opt->language_override); } if (opt->partial_filter_expression) { BSON_APPEND_DOCUMENT (&doc, "partialFilterExpression", opt->partial_filter_expression); } if (opt->geo_options) { geo_opt = opt->geo_options; def_geo = mongoc_index_opt_geo_get_default (); if (geo_opt->twod_sphere_version != def_geo->twod_sphere_version) { BSON_APPEND_INT32 (&doc, "2dsphereIndexVersion", geo_opt->twod_sphere_version); } if (geo_opt->twod_bits_precision != def_geo->twod_bits_precision) { BSON_APPEND_INT32 (&doc, "bits", geo_opt->twod_bits_precision); } if (geo_opt->twod_location_min != def_geo->twod_location_min) { BSON_APPEND_DOUBLE (&doc, "min", geo_opt->twod_location_min); } if (geo_opt->twod_location_max != def_geo->twod_location_max) { BSON_APPEND_DOUBLE (&doc, "max", geo_opt->twod_location_max); } if (geo_opt->haystack_bucket_size != def_geo->haystack_bucket_size) { BSON_APPEND_DOUBLE (&doc, "bucketSize", geo_opt->haystack_bucket_size); } } if (opt->storage_options) { storage_opt = opt->storage_options; switch (storage_opt->type) { case MONGOC_INDEX_STORAGE_OPT_WIREDTIGER: wt_opt = (mongoc_index_opt_wt_t *)storage_opt; BSON_APPEND_DOCUMENT_BEGIN (&doc, "storageEngine", &storage_doc); BSON_APPEND_DOCUMENT_BEGIN (&storage_doc, "wiredTiger", &wt_doc); BSON_APPEND_UTF8 (&wt_doc, "configString", wt_opt->config_str); bson_append_document_end (&storage_doc, &wt_doc); bson_append_document_end (&doc, &storage_doc); break; default: break; } } bson_append_document_end (&ar, &doc); bson_append_array_end (&cmd, &ar); ret = mongoc_collection_command_simple (collection, &cmd, NULL, &reply, &local_error); /* * If we failed due to the command not being found, then use the legacy * version which performs an insert into the system.indexes collection. */ if (!ret) { if (local_error.code == MONGOC_ERROR_QUERY_COMMAND_NOT_FOUND) { ret = _mongoc_collection_create_index_legacy (collection, keys, opt, error); } else if (error) { memcpy (error, &local_error, sizeof *error); } } bson_destroy (&cmd); bson_destroy (&reply); bson_free (alloc_name); return ret; } bool mongoc_collection_ensure_index (mongoc_collection_t *collection, const bson_t *keys, const mongoc_index_opt_t *opt, bson_error_t *error) { return mongoc_collection_create_index (collection, keys, opt, error); } mongoc_cursor_t * _mongoc_collection_find_indexes_legacy (mongoc_collection_t *collection, bson_error_t *error) { mongoc_database_t *db; mongoc_collection_t *idx_collection; mongoc_read_prefs_t *read_prefs; bson_t query = BSON_INITIALIZER; mongoc_cursor_t *cursor; BSON_ASSERT (collection); BSON_APPEND_UTF8 (&query, "ns", collection->ns); db = mongoc_client_get_database (collection->client, collection->db); BSON_ASSERT (db); idx_collection = mongoc_database_get_collection (db, "system.indexes"); BSON_ASSERT (idx_collection); read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); cursor = mongoc_collection_find (idx_collection, MONGOC_QUERY_NONE, 0, 0, 0, &query, NULL, read_prefs); mongoc_read_prefs_destroy (read_prefs); mongoc_collection_destroy (idx_collection); mongoc_database_destroy (db); return cursor; } mongoc_cursor_t * mongoc_collection_find_indexes (mongoc_collection_t *collection, bson_error_t *error) { mongoc_cursor_t *cursor; bson_t cmd = BSON_INITIALIZER; bson_t child; BSON_ASSERT (collection); bson_append_utf8 (&cmd, "listIndexes", -1, collection->collection, collection->collectionlen); BSON_APPEND_DOCUMENT_BEGIN (&cmd, "cursor", &child); bson_append_document_end (&cmd, &child); cursor = _mongoc_collection_cursor_new (collection, MONGOC_QUERY_SLAVE_OK); _mongoc_cursor_cursorid_init (cursor, &cmd); if (_mongoc_cursor_cursorid_prime (cursor)) { /* intentionally empty */ } else { if (mongoc_cursor_error (cursor, error)) { mongoc_cursor_destroy (cursor); if (error->code == MONGOC_ERROR_COLLECTION_DOES_NOT_EXIST) { bson_t empty_arr = BSON_INITIALIZER; /* collection does not exist. in accordance with the spec we return * an empty array. Also we need to clear out the error. */ error->code = 0; error->domain = 0; cursor = _mongoc_collection_cursor_new (collection, MONGOC_QUERY_SLAVE_OK); _mongoc_cursor_array_init (cursor, NULL, NULL); _mongoc_cursor_array_set_bson (cursor, &empty_arr); } else if (error->code == MONGOC_ERROR_QUERY_COMMAND_NOT_FOUND) { /* talking to an old server. */ /* clear out error. */ error->code = 0; error->domain = 0; cursor = _mongoc_collection_find_indexes_legacy (collection, error); } } } bson_destroy (&cmd); return cursor; } /* *-------------------------------------------------------------------------- * * mongoc_collection_insert_bulk -- * * Bulk insert documents into a MongoDB collection. * * Parameters: * @collection: A mongoc_collection_t. * @flags: flags for the insert or 0. * @documents: The documents to insert. * @n_documents: The number of documents to insert. * @write_concern: A write concern or NULL. * @error: a location for an error or NULL. * * Returns: * true if successful; otherwise false and @error is set. * * If the write concern does not dictate checking the result of the * insert, then true may be returned even though the document was * not actually inserted on the MongoDB server or cluster. * * Side effects: * @collection->gle is setup, depending on write_concern->w value. * @error may be set upon failure if non-NULL. * *-------------------------------------------------------------------------- */ bool mongoc_collection_insert_bulk (mongoc_collection_t *collection, mongoc_insert_flags_t flags, const bson_t **documents, uint32_t n_documents, const mongoc_write_concern_t *write_concern, bson_error_t *error) { mongoc_write_command_t command; mongoc_write_result_t result; mongoc_bulk_write_flags_t write_flags = MONGOC_BULK_WRITE_FLAGS_INIT; bool ret; uint32_t i; BSON_ASSERT (collection); BSON_ASSERT (documents); if (!write_concern) { write_concern = collection->write_concern; } if (!(flags & MONGOC_INSERT_NO_VALIDATE)) { int vflags = (BSON_VALIDATE_UTF8 | BSON_VALIDATE_UTF8_ALLOW_NULL | BSON_VALIDATE_DOLLAR_KEYS | BSON_VALIDATE_DOT_KEYS); for (i = 0; i < n_documents; i++) { if (!bson_validate (documents[i], (bson_validate_flags_t)vflags, NULL)) { bson_set_error (error, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, "A document was corrupt or contained " "invalid characters . or $"); RETURN (false); } } } bson_clear (&collection->gle); _mongoc_write_result_init (&result); write_flags.ordered = !(flags & MONGOC_INSERT_CONTINUE_ON_ERROR); _mongoc_write_command_init_insert (&command, NULL, write_flags, true); for (i = 0; i < n_documents; i++) { _mongoc_write_command_insert_append (&command, documents[i]); } _mongoc_collection_write_command_execute (&command, collection, write_concern, &result); collection->gle = bson_new (); ret = _mongoc_write_result_complete (&result, collection->gle, error); _mongoc_write_result_destroy (&result); _mongoc_write_command_destroy (&command); return ret; } /* *-------------------------------------------------------------------------- * * mongoc_collection_insert -- * * Insert a document into a MongoDB collection. * * Parameters: * @collection: A mongoc_collection_t. * @flags: flags for the insert or 0. * @document: The document to insert. * @write_concern: A write concern or NULL. * @error: a location for an error or NULL. * * Returns: * true if successful; otherwise false and @error is set. * * If the write concern does not dictate checking the result of the * insert, then true may be returned even though the document was * not actually inserted on the MongoDB server or cluster. * * Side effects: * @collection->gle is setup, depending on write_concern->w value. * @error may be set upon failure if non-NULL. * *-------------------------------------------------------------------------- */ bool mongoc_collection_insert (mongoc_collection_t *collection, mongoc_insert_flags_t flags, const bson_t *document, const mongoc_write_concern_t *write_concern, bson_error_t *error) { mongoc_bulk_write_flags_t write_flags = MONGOC_BULK_WRITE_FLAGS_INIT; mongoc_write_command_t command; mongoc_write_result_t result; bool ret; ENTRY; BSON_ASSERT (collection); BSON_ASSERT (document); bson_clear (&collection->gle); if (!write_concern) { write_concern = collection->write_concern; } if (!(flags & MONGOC_INSERT_NO_VALIDATE)) { int vflags = (BSON_VALIDATE_UTF8 | BSON_VALIDATE_UTF8_ALLOW_NULL | BSON_VALIDATE_DOLLAR_KEYS | BSON_VALIDATE_DOT_KEYS); if (!bson_validate (document, (bson_validate_flags_t)vflags, NULL)) { bson_set_error (error, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, "A document was corrupt or contained " "invalid characters . or $"); RETURN (false); } } _mongoc_write_result_init (&result); _mongoc_write_command_init_insert (&command, document, write_flags, false); _mongoc_collection_write_command_execute (&command, collection, write_concern, &result); collection->gle = bson_new (); ret = _mongoc_write_result_complete (&result, collection->gle, error); _mongoc_write_result_destroy (&result); _mongoc_write_command_destroy (&command); RETURN (ret); } /* *-------------------------------------------------------------------------- * * mongoc_collection_update -- * * Updates one or more documents matching @selector with @update. * * Parameters: * @collection: A mongoc_collection_t. * @flags: The flags for the update. * @selector: A bson_t containing your selector. * @update: A bson_t containing your update document. * @write_concern: The write concern or NULL. * @error: A location for an error or NULL. * * Returns: * true if successful; otherwise false and @error is set. * * Side effects: * @collection->gle is setup, depending on write_concern->w value. * @error is setup upon failure. * *-------------------------------------------------------------------------- */ bool mongoc_collection_update (mongoc_collection_t *collection, mongoc_update_flags_t uflags, const bson_t *selector, const bson_t *update, const mongoc_write_concern_t *write_concern, bson_error_t *error) { mongoc_bulk_write_flags_t write_flags = MONGOC_BULK_WRITE_FLAGS_INIT; mongoc_write_command_t command; mongoc_write_result_t result; bson_iter_t iter; size_t err_offset; bool ret; int vflags = (BSON_VALIDATE_UTF8 | BSON_VALIDATE_UTF8_ALLOW_NULL | BSON_VALIDATE_DOLLAR_KEYS | BSON_VALIDATE_DOT_KEYS); int flags = uflags; ENTRY; BSON_ASSERT (collection); BSON_ASSERT (selector); BSON_ASSERT (update); bson_clear (&collection->gle); if (!write_concern) { write_concern = collection->write_concern; } if (!((uint32_t)flags & MONGOC_UPDATE_NO_VALIDATE) && bson_iter_init (&iter, update) && bson_iter_next (&iter) && (bson_iter_key (&iter) [0] != '$') && !bson_validate (update, (bson_validate_flags_t)vflags, &err_offset)) { bson_set_error (error, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, "update document is corrupt or contains " "invalid keys including $ or ."); return false; } else { flags = (uint32_t)flags & ~MONGOC_UPDATE_NO_VALIDATE; } _mongoc_write_result_init (&result); _mongoc_write_command_init_update (&command, selector, update, !!(flags & MONGOC_UPDATE_UPSERT), !!(flags & MONGOC_UPDATE_MULTI_UPDATE), write_flags); _mongoc_collection_write_command_execute (&command, collection, write_concern, &result); collection->gle = bson_new (); ret = _mongoc_write_result_complete (&result, collection->gle, error); _mongoc_write_result_destroy (&result); _mongoc_write_command_destroy (&command); RETURN (ret); } /* *-------------------------------------------------------------------------- * * mongoc_collection_save -- * * Save @document to @collection. * * If the document has an _id field, it will be updated. Otherwise, * the document will be inserted into the collection. * * Returns: * true if successful; otherwise false and @error is set. * * Side effects: * @error is set upon failure if non-NULL. * *-------------------------------------------------------------------------- */ bool mongoc_collection_save (mongoc_collection_t *collection, const bson_t *document, const mongoc_write_concern_t *write_concern, bson_error_t *error) { bson_iter_t iter; bool ret; bson_t selector; BSON_ASSERT (collection); BSON_ASSERT (document); if (!bson_iter_init_find(&iter, document, "_id")) { return mongoc_collection_insert(collection, MONGOC_INSERT_NONE, document, write_concern, error); } bson_init(&selector); if (!bson_append_iter(&selector, NULL, 0, &iter)) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "Failed to append bson to create update."); bson_destroy (&selector); return NULL; } ret = mongoc_collection_update(collection, MONGOC_UPDATE_UPSERT, &selector, document, write_concern, error); bson_destroy(&selector); return ret; } /* *-------------------------------------------------------------------------- * * mongoc_collection_remove -- * * Delete one or more items from a collection. If you want to * limit to a single delete, provided MONGOC_REMOVE_SINGLE_REMOVE * for @flags. * * Parameters: * @collection: A mongoc_collection_t. * @flags: the delete flags or 0. * @selector: A selector of documents to delete. * @write_concern: A write concern or NULL. If NULL, the default * write concern for the collection will be used. * @error: A location for an error or NULL. * * Returns: * true if successful; otherwise false and error is set. * * If the write concern does not dictate checking the result, this * function may return true even if it failed. * * Side effects: * @collection->gle is setup, depending on write_concern->w value. * @error is setup upon failure. * *-------------------------------------------------------------------------- */ bool mongoc_collection_remove (mongoc_collection_t *collection, mongoc_remove_flags_t flags, const bson_t *selector, const mongoc_write_concern_t *write_concern, bson_error_t *error) { mongoc_bulk_write_flags_t write_flags = MONGOC_BULK_WRITE_FLAGS_INIT; mongoc_write_command_t command; mongoc_write_result_t result; bool multi; bool ret; ENTRY; BSON_ASSERT (collection); BSON_ASSERT (selector); bson_clear (&collection->gle); if (!write_concern) { write_concern = collection->write_concern; } multi = !(flags & MONGOC_REMOVE_SINGLE_REMOVE); _mongoc_write_result_init (&result); _mongoc_write_command_init_delete (&command, selector, multi, write_flags); _mongoc_collection_write_command_execute (&command, collection, write_concern, &result); collection->gle = bson_new (); ret = _mongoc_write_result_complete (&result, collection->gle, error); _mongoc_write_result_destroy (&result); _mongoc_write_command_destroy (&command); RETURN (ret); } bool mongoc_collection_delete (mongoc_collection_t *collection, mongoc_delete_flags_t flags, const bson_t *selector, const mongoc_write_concern_t *write_concern, bson_error_t *error) { return mongoc_collection_remove (collection, (mongoc_remove_flags_t)flags, selector, write_concern, error); } /* *-------------------------------------------------------------------------- * * mongoc_collection_get_read_prefs -- * * Fetch the default read preferences for the collection. * * Returns: * A mongoc_read_prefs_t that should not be modified or freed. * * Side effects: * None. * *-------------------------------------------------------------------------- */ const mongoc_read_prefs_t * mongoc_collection_get_read_prefs (const mongoc_collection_t *collection) { BSON_ASSERT (collection); return collection->read_prefs; } /* *-------------------------------------------------------------------------- * * mongoc_collection_set_read_prefs -- * * Sets the default read preferences for the collection instance. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void mongoc_collection_set_read_prefs (mongoc_collection_t *collection, const mongoc_read_prefs_t *read_prefs) { BSON_ASSERT (collection); if (collection->read_prefs) { mongoc_read_prefs_destroy(collection->read_prefs); collection->read_prefs = NULL; } if (read_prefs) { collection->read_prefs = mongoc_read_prefs_copy(read_prefs); } } /* *-------------------------------------------------------------------------- * * mongoc_collection_get_read_concern -- * * Fetches the default read concern for the collection instance. * * Returns: * A mongoc_read_concern_t that should not be modified or freed. * * Side effects: * None. * *-------------------------------------------------------------------------- */ const mongoc_read_concern_t * mongoc_collection_get_read_concern (const mongoc_collection_t *collection) { BSON_ASSERT (collection); return collection->read_concern; } /* *-------------------------------------------------------------------------- * * mongoc_collection_set_read_concern -- * * Sets the default read concern for the collection instance. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void mongoc_collection_set_read_concern (mongoc_collection_t *collection, const mongoc_read_concern_t *read_concern) { BSON_ASSERT (collection); if (collection->read_concern) { mongoc_read_concern_destroy (collection->read_concern); collection->read_concern = NULL; } if (read_concern) { collection->read_concern = mongoc_read_concern_copy (read_concern); } } /* *-------------------------------------------------------------------------- * * mongoc_collection_get_write_concern -- * * Fetches the default write concern for the collection instance. * * Returns: * A mongoc_write_concern_t that should not be modified or freed. * * Side effects: * None. * *-------------------------------------------------------------------------- */ const mongoc_write_concern_t * mongoc_collection_get_write_concern (const mongoc_collection_t *collection) { BSON_ASSERT (collection); return collection->write_concern; } /* *-------------------------------------------------------------------------- * * mongoc_collection_set_write_concern -- * * Sets the default write concern for the collection instance. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void mongoc_collection_set_write_concern (mongoc_collection_t *collection, const mongoc_write_concern_t *write_concern) { BSON_ASSERT (collection); if (collection->write_concern) { mongoc_write_concern_destroy(collection->write_concern); collection->write_concern = NULL; } if (write_concern) { collection->write_concern = mongoc_write_concern_copy(write_concern); } } /* *-------------------------------------------------------------------------- * * mongoc_collection_get_name -- * * Returns the name of the collection, excluding the database name. * * Returns: * A string which should not be modified or freed. * * Side effects: * None. * *-------------------------------------------------------------------------- */ const char * mongoc_collection_get_name (mongoc_collection_t *collection) { BSON_ASSERT (collection); return collection->collection; } /* *-------------------------------------------------------------------------- * * mongoc_collection_get_last_error -- * * Returns getLastError document, according to write_concern on last * executed command for current collection instance. * * Returns: * NULL or a bson_t that should not be modified or freed. This value * is not guaranteed to be persistent between calls into the * mongoc_collection_t instance, and therefore must be copied if * you would like to keep it around. * * Side effects: * None. * *-------------------------------------------------------------------------- */ const bson_t * mongoc_collection_get_last_error (const mongoc_collection_t *collection) /* IN */ { BSON_ASSERT (collection); return collection->gle; } /* *-------------------------------------------------------------------------- * * mongoc_collection_validate -- * * Helper to call the validate command on the MongoDB server to * validate the collection. * * Options may be additional options, or NULL. * Currently supported options are: * * "full": Boolean * * If full is true, then perform a more resource intensive * validation. * * The result is stored in reply. * * Returns: * true if successful; otherwise false and @error is set. * * Side effects: * @reply is set if successful. * @error may be set. * *-------------------------------------------------------------------------- */ bool mongoc_collection_validate (mongoc_collection_t *collection, /* IN */ const bson_t *options, /* IN */ bson_t *reply, /* OUT */ bson_error_t *error) /* IN */ { bson_iter_t iter; bson_t cmd = BSON_INITIALIZER; bool ret; BSON_ASSERT (collection); if (options && bson_iter_init_find (&iter, options, "full") && !BSON_ITER_HOLDS_BOOL (&iter)) { bson_set_error (error, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, "'full' must be a boolean value."); return false; } bson_append_utf8 (&cmd, "validate", 8, collection->collection, collection->collectionlen); if (options) { bson_concat (&cmd, options); } ret = mongoc_collection_command_simple (collection, &cmd, NULL, reply, error); bson_destroy (&cmd); return ret; } /* *-------------------------------------------------------------------------- * * mongoc_collection_rename -- * * Rename the collection to @new_name. * * If @new_db is NULL, the same db will be used. * * If @drop_target_before_rename is true, then a collection named * @new_name will be dropped before renaming @collection to * @new_name. * * Returns: * true on success; false on failure and @error is set. * * Side effects: * @error is set on failure. * *-------------------------------------------------------------------------- */ bool mongoc_collection_rename (mongoc_collection_t *collection, const char *new_db, const char *new_name, bool drop_target_before_rename, bson_error_t *error) { bson_t cmd = BSON_INITIALIZER; char newns [MONGOC_NAMESPACE_MAX + 1]; bool ret; BSON_ASSERT (collection); BSON_ASSERT (new_name); if (!validate_name (new_name)) { bson_set_error (error, MONGOC_ERROR_NAMESPACE, MONGOC_ERROR_NAMESPACE_INVALID, "\"%s\" is an invalid collection name.", new_name); return false; } bson_snprintf (newns, sizeof newns, "%s.%s", new_db ? new_db : collection->db, new_name); BSON_APPEND_UTF8 (&cmd, "renameCollection", collection->ns); BSON_APPEND_UTF8 (&cmd, "to", newns); if (drop_target_before_rename) { BSON_APPEND_BOOL (&cmd, "dropTarget", true); } ret = mongoc_client_command_simple (collection->client, "admin", &cmd, NULL, NULL, error); if (ret) { if (new_db) { bson_snprintf (collection->db, sizeof collection->db, "%s", new_db); } bson_snprintf (collection->collection, sizeof collection->collection, "%s", new_name); collection->collectionlen = (int) strlen (collection->collection); bson_snprintf (collection->ns, sizeof collection->ns, "%s.%s", collection->db, new_name); collection->nslen = (int) strlen (collection->ns); } bson_destroy (&cmd); return ret; } /* *-------------------------------------------------------------------------- * * mongoc_collection_stats -- * * Fetches statistics about the collection. * * The result is stored in @stats, which should NOT be an initialized * bson_t or a leak will occur. * * @stats, @options, and @error are optional. * * Returns: * true on success and @stats is set. * false on failure and @error is set. * * Side effects: * @stats and @error. * *-------------------------------------------------------------------------- */ bool mongoc_collection_stats (mongoc_collection_t *collection, const bson_t *options, bson_t *stats, bson_error_t *error) { bson_iter_t iter; bson_t cmd = BSON_INITIALIZER; bool ret; BSON_ASSERT (collection); if (options && bson_iter_init_find (&iter, options, "scale") && !BSON_ITER_HOLDS_INT32 (&iter)) { bson_set_error (error, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, "'scale' must be an int32 value."); return false; } BSON_APPEND_UTF8 (&cmd, "collStats", collection->collection); if (options) { bson_concat (&cmd, options); } ret = mongoc_collection_command_simple (collection, &cmd, NULL, stats, error); bson_destroy (&cmd); return ret; } mongoc_bulk_operation_t * mongoc_collection_create_bulk_operation ( mongoc_collection_t *collection, bool ordered, const mongoc_write_concern_t *write_concern) { mongoc_bulk_write_flags_t write_flags = MONGOC_BULK_WRITE_FLAGS_INIT; BSON_ASSERT (collection); if (!write_concern) { write_concern = collection->write_concern; } write_flags.ordered = ordered; return _mongoc_bulk_operation_new (collection->client, collection->db, collection->collection, write_flags, write_concern); } /* *-------------------------------------------------------------------------- * * mongoc_collection_find_and_modify_with_opts -- * * Find a document in @collection matching @query, applying @opts. * * If @reply is not NULL, then the result document will be placed * in reply and should be released with bson_destroy(). * * See http://docs.mongodb.org/manual/reference/command/findAndModify/ * for more information. * * Returns: * true on success; false on failure. * * Side effects: * reply is initialized. * error is set if false is returned. * *-------------------------------------------------------------------------- */ bool mongoc_collection_find_and_modify_with_opts (mongoc_collection_t *collection, const bson_t *query, const mongoc_find_and_modify_opts_t *opts, bson_t *reply, bson_error_t *error) { mongoc_cluster_t *cluster; mongoc_server_stream_t *server_stream; bson_iter_t iter; bson_iter_t inner; const char *name; bson_t reply_local; bool ret; bson_t command = BSON_INITIALIZER; ENTRY; BSON_ASSERT (collection); BSON_ASSERT (query); cluster = &collection->client->cluster; server_stream = mongoc_cluster_stream_for_writes (cluster, error); if (!server_stream) { bson_destroy (&command); RETURN (false); } name = mongoc_collection_get_name (collection); BSON_APPEND_UTF8 (&command, "findAndModify", name); BSON_APPEND_DOCUMENT (&command, "query", query); if (opts->sort) { BSON_APPEND_DOCUMENT (&command, "sort", opts->sort); } if (opts->update) { BSON_APPEND_DOCUMENT (&command, "update", opts->update); } if (opts->fields) { BSON_APPEND_DOCUMENT (&command, "fields", opts->fields); } if (opts->flags & MONGOC_FIND_AND_MODIFY_REMOVE) { BSON_APPEND_BOOL (&command, "remove", true); } if (opts->flags & MONGOC_FIND_AND_MODIFY_UPSERT) { BSON_APPEND_BOOL (&command, "upsert", true); } if (opts->flags & MONGOC_FIND_AND_MODIFY_RETURN_NEW) { BSON_APPEND_BOOL (&command, "new", true); } if (opts->bypass_document_validation != MONGOC_BYPASS_DOCUMENT_VALIDATION_DEFAULT) { BSON_APPEND_BOOL (&command, "bypassDocumentValidation", !!opts->bypass_document_validation); } if (server_stream->sd->max_wire_version >= WIRE_VERSION_FAM_WRITE_CONCERN) { if (!_mongoc_write_concern_is_valid (collection->write_concern)) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "The write concern is invalid."); bson_destroy (&command); mongoc_server_stream_cleanup (server_stream); RETURN (false); } if (_mongoc_write_concern_needs_gle (collection->write_concern)) { _BSON_APPEND_WRITE_CONCERN (&command, collection->write_concern); } } ret = mongoc_cluster_run_command (cluster, server_stream->stream, server_stream->sd->id, MONGOC_QUERY_NONE, collection->db, &command, &reply_local, error); if (bson_iter_init_find (&iter, &reply_local, "writeConcernError") && BSON_ITER_HOLDS_DOCUMENT (&iter)) { const char *errmsg = NULL; int32_t code = 0; bson_iter_recurse(&iter, &inner); while (bson_iter_next (&inner)) { if (BSON_ITER_IS_KEY (&inner, "code")) { code = bson_iter_int32 (&inner); } else if (BSON_ITER_IS_KEY (&inner, "errmsg")) { errmsg = bson_iter_utf8 (&inner, NULL); } } bson_set_error (error, MONGOC_ERROR_WRITE_CONCERN, code, "Write Concern error: %s", errmsg); } if (reply) { bson_copy_to (&reply_local, reply); } bson_destroy (&reply_local); bson_destroy (&command); mongoc_server_stream_cleanup (server_stream); RETURN (ret); } /* *-------------------------------------------------------------------------- * * mongoc_collection_find_and_modify -- * * Find a document in @collection matching @query and update it with * the update document @update. * * If @reply is not NULL, then the result document will be placed * in reply and should be released with bson_destroy(). * * If @remove is true, then the matching documents will be removed. * * If @fields is not NULL, it will be used to select the desired * resulting fields. * * If @_new is true, then the new version of the document is returned * instead of the old document. * * See http://docs.mongodb.org/manual/reference/command/findAndModify/ * for more information. * * Returns: * true on success; false on failure. * * Side effects: * reply is initialized. * error is set if false is returned. * *-------------------------------------------------------------------------- */ bool mongoc_collection_find_and_modify (mongoc_collection_t *collection, const bson_t *query, const bson_t *sort, const bson_t *update, const bson_t *fields, bool _remove, bool upsert, bool _new, bson_t *reply, bson_error_t *error) { mongoc_find_and_modify_opts_t *opts; int flags = 0; bool ret; ENTRY; BSON_ASSERT (collection); BSON_ASSERT (query); BSON_ASSERT (update || _remove); if (_remove) { flags |= MONGOC_FIND_AND_MODIFY_REMOVE; } if (upsert) { flags |= MONGOC_FIND_AND_MODIFY_UPSERT; } if (_new) { flags |= MONGOC_FIND_AND_MODIFY_RETURN_NEW; } opts = mongoc_find_and_modify_opts_new (); mongoc_find_and_modify_opts_set_sort (opts, sort); mongoc_find_and_modify_opts_set_update (opts, update); mongoc_find_and_modify_opts_set_fields (opts, fields); mongoc_find_and_modify_opts_set_flags (opts, flags); ret = mongoc_collection_find_and_modify_with_opts (collection, query, opts, reply, error); mongoc_find_and_modify_opts_destroy (opts); return ret; } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-collection.h0000664000175000017500000003743712673034026023421 0ustar jmikolajmikola/* * Copyright 2013-2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_COLLECTION_H #define MONGOC_COLLECTION_H #if !defined (MONGOC_INSIDE) && !defined (MONGOC_COMPILATION) # error "Only can be included directly." #endif #include #include "mongoc-bulk-operation.h" #include "mongoc-flags.h" #include "mongoc-cursor.h" #include "mongoc-index.h" #include "mongoc-read-prefs.h" #include "mongoc-read-concern.h" #include "mongoc-write-concern.h" #include "mongoc-find-and-modify.h" BSON_BEGIN_DECLS typedef struct _mongoc_collection_t mongoc_collection_t; mongoc_cursor_t *mongoc_collection_aggregate (mongoc_collection_t *collection, mongoc_query_flags_t flags, const bson_t *pipeline, const bson_t *options, const mongoc_read_prefs_t *read_prefs) BSON_GNUC_WARN_UNUSED_RESULT; void mongoc_collection_destroy (mongoc_collection_t *collection); mongoc_collection_t *mongoc_collection_copy (mongoc_collection_t *collection); mongoc_cursor_t *mongoc_collection_command (mongoc_collection_t *collection, mongoc_query_flags_t flags, uint32_t skip, uint32_t limit, uint32_t batch_size, const bson_t *command, const bson_t *fields, const mongoc_read_prefs_t *read_prefs) BSON_GNUC_WARN_UNUSED_RESULT; bool mongoc_collection_command_simple (mongoc_collection_t *collection, const bson_t *command, const mongoc_read_prefs_t *read_prefs, bson_t *reply, bson_error_t *error); int64_t mongoc_collection_count (mongoc_collection_t *collection, mongoc_query_flags_t flags, const bson_t *query, int64_t skip, int64_t limit, const mongoc_read_prefs_t *read_prefs, bson_error_t *error); int64_t mongoc_collection_count_with_opts (mongoc_collection_t *collection, mongoc_query_flags_t flags, const bson_t *query, int64_t skip, int64_t limit, const bson_t *opts, const mongoc_read_prefs_t *read_prefs, bson_error_t *error); bool mongoc_collection_drop (mongoc_collection_t *collection, bson_error_t *error); bool mongoc_collection_drop_index (mongoc_collection_t *collection, const char *index_name, bson_error_t *error); bool mongoc_collection_create_index (mongoc_collection_t *collection, const bson_t *keys, const mongoc_index_opt_t *opt, bson_error_t *error); bool mongoc_collection_ensure_index (mongoc_collection_t *collection, const bson_t *keys, const mongoc_index_opt_t *opt, bson_error_t *error) BSON_GNUC_DEPRECATED_FOR (mongoc_collection_create_index); mongoc_cursor_t *mongoc_collection_find_indexes (mongoc_collection_t *collection, bson_error_t *error); mongoc_cursor_t *mongoc_collection_find (mongoc_collection_t *collection, mongoc_query_flags_t flags, uint32_t skip, uint32_t limit, uint32_t batch_size, const bson_t *query, const bson_t *fields, const mongoc_read_prefs_t *read_prefs) BSON_GNUC_WARN_UNUSED_RESULT; bool mongoc_collection_insert (mongoc_collection_t *collection, mongoc_insert_flags_t flags, const bson_t *document, const mongoc_write_concern_t *write_concern, bson_error_t *error); bool mongoc_collection_insert_bulk (mongoc_collection_t *collection, mongoc_insert_flags_t flags, const bson_t **documents, uint32_t n_documents, const mongoc_write_concern_t *write_concern, bson_error_t *error) BSON_GNUC_DEPRECATED_FOR (mongoc_collection_create_bulk_operation); bool mongoc_collection_update (mongoc_collection_t *collection, mongoc_update_flags_t flags, const bson_t *selector, const bson_t *update, const mongoc_write_concern_t *write_concern, bson_error_t *error); bool mongoc_collection_delete (mongoc_collection_t *collection, mongoc_delete_flags_t flags, const bson_t *selector, const mongoc_write_concern_t *write_concern, bson_error_t *error) BSON_GNUC_DEPRECATED_FOR (mongoc_collection_remove); bool mongoc_collection_save (mongoc_collection_t *collection, const bson_t *document, const mongoc_write_concern_t *write_concern, bson_error_t *error); bool mongoc_collection_remove (mongoc_collection_t *collection, mongoc_remove_flags_t flags, const bson_t *selector, const mongoc_write_concern_t *write_concern, bson_error_t *error); bool mongoc_collection_rename (mongoc_collection_t *collection, const char *new_db, const char *new_name, bool drop_target_before_rename, bson_error_t *error); bool mongoc_collection_find_and_modify_with_opts (mongoc_collection_t *collection, const bson_t *query, const mongoc_find_and_modify_opts_t *opts, bson_t *reply, bson_error_t *error); bool mongoc_collection_find_and_modify (mongoc_collection_t *collection, const bson_t *query, const bson_t *sort, const bson_t *update, const bson_t *fields, bool _remove, bool upsert, bool _new, bson_t *reply, bson_error_t *error); bool mongoc_collection_stats (mongoc_collection_t *collection, const bson_t *options, bson_t *reply, bson_error_t *error); mongoc_bulk_operation_t *mongoc_collection_create_bulk_operation(mongoc_collection_t *collection, bool ordered, const mongoc_write_concern_t *write_concern) BSON_GNUC_WARN_UNUSED_RESULT; const mongoc_read_prefs_t *mongoc_collection_get_read_prefs (const mongoc_collection_t *collection); void mongoc_collection_set_read_prefs (mongoc_collection_t *collection, const mongoc_read_prefs_t *read_prefs); const mongoc_read_concern_t *mongoc_collection_get_read_concern (const mongoc_collection_t *collection); void mongoc_collection_set_read_concern (mongoc_collection_t *collection, const mongoc_read_concern_t *read_concern); const mongoc_write_concern_t *mongoc_collection_get_write_concern (const mongoc_collection_t *collection); void mongoc_collection_set_write_concern (mongoc_collection_t *collection, const mongoc_write_concern_t *write_concern); const char *mongoc_collection_get_name (mongoc_collection_t *collection); const bson_t *mongoc_collection_get_last_error (const mongoc_collection_t *collection); char *mongoc_collection_keys_to_index_string (const bson_t *keys); bool mongoc_collection_validate (mongoc_collection_t *collection, const bson_t *options, bson_t *reply, bson_error_t *error); BSON_END_DECLS #endif /* MONGOC_COLLECTION_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-config.h0000664000175000017500000000334112673034026022516 0ustar jmikolajmikola/* * Copyright 2013 MongoDB Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_CONFIG_H #define MONGOC_CONFIG_H /* * MONGOC_ENABLE_SSL is set from configure to determine if we are * compiled with SSL support. */ #define MONGOC_ENABLE_SSL 1 #if MONGOC_ENABLE_SSL != 1 # undef MONGOC_ENABLE_SSL #endif /* * MONGOC_ENABLE_SASL is set from configure to determine if we are * compiled with SASL support. */ #define MONGOC_ENABLE_SASL 1 #if MONGOC_ENABLE_SASL != 1 # undef MONGOC_ENABLE_SASL #endif /* * MONGOC_HAVE_SASL_CLIENT_DONE is set from configure to determine if we * have SASL and its version is new enough to use sasl_client_done (), * which supersedes sasl_done (). */ #define MONGOC_HAVE_SASL_CLIENT_DONE 1 #if MONGOC_HAVE_SASL_CLIENT_DONE != 1 # undef MONGOC_HAVE_SASL_CLIENT_DONE #endif /* * MONGOC_HAVE_WEAK_SYMBOLS is set from configure to determine if the * compiler supports the (weak) annotation. We use it to prevent * Link-Time-Optimization (LTO) in our constant-time mongoc_memcmp() * This is known to work with GNU GCC and Solaris Studio */ #define MONGOC_HAVE_WEAK_SYMBOLS 1 #if MONGOC_HAVE_WEAK_SYMBOLS != 1 # undef MONGOC_HAVE_WEAK_SYMBOLS #endif #endif /* MONGOC_CONFIG_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-config.h.in0000664000175000017500000000347412673034026023132 0ustar jmikolajmikola/* * Copyright 2013 MongoDB Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_CONFIG_H #define MONGOC_CONFIG_H /* * MONGOC_ENABLE_SSL is set from configure to determine if we are * compiled with SSL support. */ #define MONGOC_ENABLE_SSL @MONGOC_ENABLE_SSL@ #if MONGOC_ENABLE_SSL != 1 # undef MONGOC_ENABLE_SSL #endif /* * MONGOC_ENABLE_SASL is set from configure to determine if we are * compiled with SASL support. */ #define MONGOC_ENABLE_SASL @MONGOC_ENABLE_SASL@ #if MONGOC_ENABLE_SASL != 1 # undef MONGOC_ENABLE_SASL #endif /* * MONGOC_HAVE_SASL_CLIENT_DONE is set from configure to determine if we * have SASL and its version is new enough to use sasl_client_done (), * which supersedes sasl_done (). */ #define MONGOC_HAVE_SASL_CLIENT_DONE @MONGOC_HAVE_SASL_CLIENT_DONE@ #if MONGOC_HAVE_SASL_CLIENT_DONE != 1 # undef MONGOC_HAVE_SASL_CLIENT_DONE #endif /* * MONGOC_HAVE_WEAK_SYMBOLS is set from configure to determine if the * compiler supports the (weak) annotation. We use it to prevent * Link-Time-Optimization (LTO) in our constant-time mongoc_memcmp() * This is known to work with GNU GCC and Solaris Studio */ #define MONGOC_HAVE_WEAK_SYMBOLS @MONGOC_HAVE_WEAK_SYMBOLS@ #if MONGOC_HAVE_WEAK_SYMBOLS != 1 # undef MONGOC_HAVE_WEAK_SYMBOLS #endif #endif /* MONGOC_CONFIG_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-counters-private.h0000664000175000017500000000735612673034026024575 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_COUNTERS_PRIVATE_H #define MONGOC_COUNTERS_PRIVATE_H #if !defined (MONGOC_I_AM_A_DRIVER) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #include #ifdef __linux__ # include # include #elif defined(__FreeBSD__) || \ defined(__NetBSD__) || \ defined(__DragonFly__) || \ defined(__OpenBSD__) # include # include # include #endif BSON_BEGIN_DECLS void _mongoc_counters_init (void); void _mongoc_counters_cleanup (void); static BSON_INLINE unsigned _mongoc_get_cpu_count (void) { #if defined(__linux__) return get_nprocs (); #elif defined(__FreeBSD__) || \ defined(__NetBSD__) || \ defined(__DragonFly__) || \ defined(__OpenBSD__) int mib[2]; int maxproc; size_t len; mib[0] = CTL_HW; mib[1] = HW_NCPU; len = sizeof (maxproc); if (-1 == sysctl (mib, 2, &maxproc, &len, NULL, 0)) { return 1; } return len; #elif defined(__APPLE__) || defined(__sun) int ncpu; ncpu = (int) sysconf (_SC_NPROCESSORS_ONLN); return (ncpu > 0) ? ncpu : 1; #elif defined(_MSC_VER) || defined(_WIN32) SYSTEM_INFO si; GetSystemInfo (&si); return si.dwNumberOfProcessors; #else # warning "_mongoc_get_cpu_count() not supported, defaulting to 1." return 1; #endif } #define _mongoc_counter_add(v,count) \ bson_atomic_int64_add(&(v), (count)) #if defined(ENABLE_RDTSCP) static BSON_INLINE unsigned _mongoc_sched_getcpu (void) { volatile uint32_t rax, rdx, aux; __asm__ volatile ("rdtscp\n" : "=a" (rax), "=d" (rdx), "=c" (aux) : : ); return aux; } #elif defined(HAVE_SCHED_GETCPU) # define _mongoc_sched_getcpu sched_getcpu #else # define _mongoc_sched_getcpu() (0) #endif #ifndef SLOTS_PER_CACHELINE # define SLOTS_PER_CACHELINE 8 #endif typedef struct { int64_t slots [SLOTS_PER_CACHELINE]; } mongoc_counter_slots_t; typedef struct { mongoc_counter_slots_t *cpus; } mongoc_counter_t; #define COUNTER(ident, Category, Name, Description) \ extern mongoc_counter_t __mongoc_counter_##ident; #include "mongoc-counters.defs" #undef COUNTER enum { #define COUNTER(ident, Category, Name, Description) \ COUNTER_##ident, #include "mongoc-counters.defs" #undef COUNTER LAST_COUNTER }; #define COUNTER(ident, Category, Name, Description) \ static BSON_INLINE void \ mongoc_counter_##ident##_add (int64_t val) \ { \ _mongoc_counter_add(\ __mongoc_counter_##ident.cpus[_mongoc_sched_getcpu()].slots[ \ COUNTER_##ident%SLOTS_PER_CACHELINE], val); \ } \ static BSON_INLINE void \ mongoc_counter_##ident##_inc (void) \ { \ mongoc_counter_##ident##_add (1); \ } \ static BSON_INLINE void \ mongoc_counter_##ident##_dec (void) \ { \ mongoc_counter_##ident##_add (-1); \ } \ static BSON_INLINE void \ mongoc_counter_##ident##_reset (void) \ { \ uint32_t i; \ for (i = 0; i < _mongoc_get_cpu_count(); i++) { \ __mongoc_counter_##ident.cpus [i].slots [\ COUNTER_##ident%SLOTS_PER_CACHELINE] = 0; \ } \ bson_memory_barrier (); \ } #include "mongoc-counters.defs" #undef COUNTER BSON_END_DECLS #endif /* MONGOC_COUNTERS_PRIVATE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-counters.c0000664000175000017500000001654012673034026023113 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #ifdef BSON_OS_UNIX #include #include #endif #ifdef _MSC_VER # include #endif #include "mongoc-counters-private.h" #include "mongoc-log.h" #pragma pack(1) typedef struct { uint32_t offset; uint32_t slot; char category[24]; char name[32]; char description[64]; } mongoc_counter_info_t; #pragma pack() BSON_STATIC_ASSERT(sizeof(mongoc_counter_info_t) == 128); #pragma pack(1) typedef struct { uint32_t size; uint32_t n_cpu; uint32_t n_counters; uint32_t infos_offset; uint32_t values_offset; uint8_t padding[44]; } mongoc_counters_t; #pragma pack() BSON_STATIC_ASSERT(sizeof(mongoc_counters_t) == 64); static void *gCounterFallback = NULL; #define COUNTER(ident, Category, Name, Description) \ mongoc_counter_t __mongoc_counter_##ident; #include "mongoc-counters.defs" #undef COUNTER /** * mongoc_counters_use_shm: * * Checks to see if counters should be exported over a shared memory segment. * * Returns: true if SHM is to be used. */ #if defined(BSON_OS_UNIX) && defined(MONGOC_ENABLE_SHM_COUNTERS) static bool mongoc_counters_use_shm (void) { return !getenv("MONGOC_DISABLE_SHM"); } #endif /** * mongoc_counters_calc_size: * * Returns the number of bytes required for the shared memory segment of * the process. This segment contains the various statistical counters for * the process. * * Returns: The number of bytes required. */ static size_t mongoc_counters_calc_size (void) { size_t n_cpu; size_t n_groups; size_t size; n_cpu = _mongoc_get_cpu_count(); n_groups = (LAST_COUNTER / SLOTS_PER_CACHELINE) + 1; size = (sizeof(mongoc_counters_t) + (LAST_COUNTER * sizeof(mongoc_counter_info_t)) + (n_cpu * n_groups * sizeof(mongoc_counter_slots_t))); #ifdef BSON_OS_UNIX return BSON_MAX(getpagesize(), size); #else return size; #endif } /** * mongoc_counters_destroy: * * Removes the shared memory segment for the current processes counters. */ void _mongoc_counters_cleanup (void) { if (gCounterFallback) { bson_free (gCounterFallback); gCounterFallback = NULL; #if defined(BSON_OS_UNIX) && defined(MONGOC_ENABLE_SHM_COUNTERS) } else { char name [32]; int pid; pid = getpid (); bson_snprintf (name, sizeof name, "/mongoc-%u", pid); shm_unlink (name); #endif } } /** * mongoc_counters_alloc: * @size: The size of the shared memory segment. * * This function allocates the shared memory segment for use by counters * within the process. * * Returns: A shared memory segment, or malloc'd memory on failure. */ static void * mongoc_counters_alloc (size_t size) { #if defined(BSON_OS_UNIX) && defined(MONGOC_ENABLE_SHM_COUNTERS) void *mem; char name[32]; int pid; int fd; if (!mongoc_counters_use_shm ()) { goto use_malloc; } pid = getpid (); bson_snprintf (name, sizeof name, "/mongoc-%u", pid); if (-1 == (fd = shm_open (name, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR))) { goto use_malloc; } /* * NOTE: * * ftruncate() will cause reads to be zero. Therefore, we don't need to * do write() of zeroes to initialize the shared memory area. */ if (-1 == ftruncate (fd, size)) { goto failure; } mem = mmap (NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if (mem == MAP_FAILED) { goto failure; } close (fd); memset (mem, 0, size); return mem; failure: shm_unlink (name); close (fd); use_malloc: MONGOC_WARNING("Falling back to malloc for counters."); #endif gCounterFallback = (void *)bson_malloc0 (size); return gCounterFallback; } /** * mongoc_counters_register: * @counters: A mongoc_counter_t. * @num: The counter number. * @category: The counter category. * @name: THe counter name. * @description The counter description. * * Registers a new counter in the memory segment for counters. If the counters * are exported over shared memory, it will be made available. * * Returns: The offset to the data for the counters values. */ static size_t mongoc_counters_register (mongoc_counters_t *counters, uint32_t num, const char *category, const char *name, const char *description) { mongoc_counter_info_t *infos; char *segment; int n_cpu; BSON_ASSERT(counters); BSON_ASSERT(category); BSON_ASSERT(name); BSON_ASSERT(description); /* * Implementation Note: * * The memory barrier is required so that all of the above has been * completed. Then increment the n_counters so that a reading application * only knows about the counter after we have initialized it. */ n_cpu = _mongoc_get_cpu_count(); segment = (char *)counters; infos = (mongoc_counter_info_t *)(segment + counters->infos_offset); infos = &infos[counters->n_counters]; infos->slot = num % SLOTS_PER_CACHELINE; infos->offset = (counters->values_offset + ((num / SLOTS_PER_CACHELINE) * n_cpu * sizeof(mongoc_counter_slots_t))); bson_strncpy (infos->category, category, sizeof infos->category); bson_strncpy (infos->name, name, sizeof infos->name); bson_strncpy (infos->description, description, sizeof infos->description); bson_memory_barrier (); counters->n_counters++; return infos->offset; } /** * mongoc_counters_init: * * Initializes the mongoc counters system. This should be run on library * initialization using the GCC constructor attribute. */ void _mongoc_counters_init (void) { mongoc_counter_info_t *info; mongoc_counters_t *counters; size_t infos_size; size_t off; size_t size; char *segment; size = mongoc_counters_calc_size(); segment = (char *)mongoc_counters_alloc(size); infos_size = LAST_COUNTER * sizeof *info; counters = (mongoc_counters_t *)segment; counters->n_cpu = _mongoc_get_cpu_count(); counters->n_counters = 0; counters->infos_offset = sizeof *counters; counters->values_offset = (uint32_t)(counters->infos_offset + infos_size); BSON_ASSERT ((counters->values_offset % 64) == 0); #define COUNTER(ident, Category, Name, Desc) \ off = mongoc_counters_register(counters, COUNTER_##ident, Category, Name, Desc); \ __mongoc_counter_##ident.cpus = (mongoc_counter_slots_t *)(segment + off); #include "mongoc-counters.defs" #undef COUNTER /* * NOTE: * * Only update the size of the shared memory area for the client after * we have initialized the rest of the counters. Don't forget our memory * barrier to prevent compiler reordering. */ bson_memory_barrier (); counters->size = (uint32_t)size; } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-counters.defs0000664000175000017500000001045012673034026023604 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ COUNTER(op_egress_total, "Operations", "Egress Total", "The number of sent operations.") COUNTER(op_ingress_total, "Operations", "Ingress Total", "The number of received operations.") COUNTER(op_egress_query, "Operations", "Egress Queries", "The number of sent Query operations.") COUNTER(op_ingress_query, "Operations", "Ingress Queries", "The number of received Query operations.") COUNTER(op_egress_getmore, "Operations", "Egress GetMore", "The number of sent GetMore operations.") COUNTER(op_ingress_getmore, "Operations", "Ingress GetMore", "The number of received GetMore operations.") COUNTER(op_egress_insert, "Operations", "Egress Insert", "The number of sent Insert operations.") COUNTER(op_ingress_insert, "Operations", "Ingress Insert", "The number of received Insert operations.") COUNTER(op_egress_delete, "Operations", "Egress Delete", "The number of sent Delete operations.") COUNTER(op_ingress_delete, "Operations", "Ingress Delete", "The number of received Delete operations.") COUNTER(op_egress_update, "Operations", "Egress Update", "The number of sent Update operations.") COUNTER(op_ingress_update, "Operations", "Ingress Update", "The number of received Update operations.") COUNTER(op_egress_killcursors, "Operations", "Egress KillCursors", "The number of sent KillCursors operations.") COUNTER(op_ingress_killcursors, "Operations", "Ingress KillCursors", "The number of received KillCursors operations.") COUNTER(op_egress_msg, "Operations", "Egress Msg", "The number of sent Msg operations.") COUNTER(op_ingress_msg, "Operations", "Ingress Msg", "The number of received Msg operations.") COUNTER(op_egress_reply, "Operations", "Egress Reply", "The number of sent Reply operations.") COUNTER(op_ingress_reply, "Operations", "Ingress Reply", "The number of received Reply operations.") COUNTER(cursors_active, "Cursors", "Active", "The number of active cursors.") COUNTER(cursors_disposed, "Cursors", "Disposed", "The number of disposed cursors.") COUNTER(clients_active, "Clients", "Active", "The number of active clients.") COUNTER(clients_disposed, "Clients", "Disposed", "The number of disposed clients.") COUNTER(streams_active, "Streams", "Active", "The number of active streams.") COUNTER(streams_disposed, "Streams", "Disposed", "The number of disposed streams.") COUNTER(streams_egress, "Streams", "Egress Bytes", "The number of bytes sent.") COUNTER(streams_ingress, "Streams", "Ingress Bytes", "The number of bytes received.") COUNTER(streams_timeout, "Streams", "N Socket Timeouts", "The number of socket timeouts.") COUNTER(client_pools_active, "Client Pools", "Active", "The number of active client pools.") COUNTER(client_pools_disposed, "Client Pools", "Disposed", "The number of disposed client pools.") COUNTER(protocol_ingress_error, "Protocol", "Ingress Errors", "The number of protocol errors on ingress.") COUNTER(auth_failure, "Auth", "Failures", "The number of failed authentication requests.") COUNTER(auth_success, "Auth", "Success", "The number of successful authentication requests.") COUNTER(dns_failure, "DNS", "Failure", "The number of failed DNS requests.") COUNTER(dns_success, "DNS", "Success", "The number of successful DNS requests.") mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-cursor-array-private.h0000664000175000017500000000240312673034026025350 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_CURSOR_ARRAY_PRIVATE_H #define MONGOC_CURSOR_ARRAY_PRIVATE_H #if !defined (MONGOC_I_AM_A_DRIVER) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #include #include "mongoc-cursor-private.h" BSON_BEGIN_DECLS void _mongoc_cursor_array_init (mongoc_cursor_t *cursor, const bson_t *command, const char *field_name); bool _mongoc_cursor_array_prime (mongoc_cursor_t *cursor); void _mongoc_cursor_array_set_bson (mongoc_cursor_t *cursor, const bson_t *bson); BSON_END_DECLS #endif /* MONGOC_CURSOR_ARRAY_PRIVATE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-cursor-array.c0000664000175000017500000001165212673034026023701 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "mongoc-cursor.h" #include "mongoc-cursor-array-private.h" #include "mongoc-cursor-private.h" #include "mongoc-client-private.h" #include "mongoc-counters-private.h" #include "mongoc-error.h" #include "mongoc-log.h" #include "mongoc-opcode.h" #include "mongoc-trace.h" #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "cursor-array" typedef struct { const bson_t *result; bool has_array; bool has_synthetic_bson; bson_iter_t iter; bson_t bson; uint32_t document_len; const uint8_t *document; const char *field_name; } mongoc_cursor_array_t; static void * _mongoc_cursor_array_new (const char *field_name) { mongoc_cursor_array_t *arr; ENTRY; arr = (mongoc_cursor_array_t *)bson_malloc0 (sizeof *arr); arr->field_name = field_name; RETURN (arr); } static void _mongoc_cursor_array_destroy (mongoc_cursor_t *cursor) { mongoc_cursor_array_t *arr; ENTRY; arr = (mongoc_cursor_array_t *)cursor->iface_data; if (arr->has_synthetic_bson) { bson_destroy(&arr->bson); } bson_free (cursor->iface_data); _mongoc_cursor_destroy (cursor); EXIT; } bool _mongoc_cursor_array_prime (mongoc_cursor_t *cursor) { const bson_t *bson; mongoc_cursor_array_t *arr; bson_iter_t iter; ENTRY; arr = (mongoc_cursor_array_t *)cursor->iface_data; BSON_ASSERT (arr); if (_mongoc_cursor_run_command (cursor, &cursor->query) && _mongoc_read_from_buffer (cursor, &bson) && bson_iter_init_find (&iter, bson, arr->field_name) && BSON_ITER_HOLDS_ARRAY (&iter) && bson_iter_recurse (&iter, &arr->iter)) { arr->has_array = true; } return arr->has_array; } static bool _mongoc_cursor_array_next (mongoc_cursor_t *cursor, const bson_t **bson) { bool ret = true; mongoc_cursor_array_t *arr; ENTRY; arr = (mongoc_cursor_array_t *)cursor->iface_data; *bson = NULL; if (!arr->has_array) { ret = _mongoc_cursor_array_prime(cursor); } if (ret) { ret = bson_iter_next (&arr->iter); } if (ret) { bson_iter_document (&arr->iter, &arr->document_len, &arr->document); bson_init_static (&arr->bson, arr->document, arr->document_len); *bson = &arr->bson; } RETURN (ret); } static mongoc_cursor_t * _mongoc_cursor_array_clone (const mongoc_cursor_t *cursor) { mongoc_cursor_array_t *arr; mongoc_cursor_t *clone_; ENTRY; arr = (mongoc_cursor_array_t *)cursor->iface_data; clone_ = _mongoc_cursor_clone (cursor); _mongoc_cursor_array_init (clone_, &cursor->query, arr->field_name); RETURN (clone_); } static bool _mongoc_cursor_array_more (mongoc_cursor_t *cursor) { bool ret; mongoc_cursor_array_t *arr; bson_iter_t iter; ENTRY; arr = (mongoc_cursor_array_t *)cursor->iface_data; if (arr->has_array) { memcpy (&iter, &arr->iter, sizeof iter); ret = bson_iter_next (&iter); } else { ret = true; } RETURN (ret); } static bool _mongoc_cursor_array_error (mongoc_cursor_t *cursor, bson_error_t *error) { mongoc_cursor_array_t *arr; ENTRY; arr = (mongoc_cursor_array_t *)cursor->iface_data; if (arr->has_synthetic_bson) { return false; } else { return _mongoc_cursor_error(cursor, error); } } static mongoc_cursor_interface_t gMongocCursorArray = { _mongoc_cursor_array_clone, _mongoc_cursor_array_destroy, _mongoc_cursor_array_more, _mongoc_cursor_array_next, _mongoc_cursor_array_error, }; void _mongoc_cursor_array_init (mongoc_cursor_t *cursor, const bson_t *command, const char *field_name) { ENTRY; if (command) { bson_destroy (&cursor->query); bson_copy_to (command, &cursor->query); } cursor->iface_data = _mongoc_cursor_array_new (field_name); memcpy (&cursor->iface, &gMongocCursorArray, sizeof (mongoc_cursor_interface_t)); EXIT; } void _mongoc_cursor_array_set_bson (mongoc_cursor_t *cursor, const bson_t *bson) { mongoc_cursor_array_t *arr; ENTRY; arr = (mongoc_cursor_array_t *)cursor->iface_data; bson_copy_to(bson, &arr->bson); arr->has_array = true; arr->has_synthetic_bson = true; bson_iter_init(&arr->iter, &arr->bson); } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-cursor-cursorid-private.h0000664000175000017500000000257712673034026026100 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_CURSOR_CURSORID_PRIVATE_H #define MONGOC_CURSOR_CURSORID_PRIVATE_H #if !defined (MONGOC_I_AM_A_DRIVER) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #include #include "mongoc-cursor-private.h" BSON_BEGIN_DECLS typedef struct { bool in_batch; bool in_reader; bson_iter_t batch_iter; bson_t current_doc; } mongoc_cursor_cursorid_t; bool _mongoc_cursor_cursorid_prime (mongoc_cursor_t *cursor); bool _mongoc_cursor_cursorid_next (mongoc_cursor_t *cursor, const bson_t **bson); void _mongoc_cursor_cursorid_init (mongoc_cursor_t *cursor, const bson_t *command); BSON_END_DECLS #endif /* MONGOC_CURSOR_CURSORID_PRIVATE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-cursor-cursorid.c0000664000175000017500000001701612673034026024415 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "mongoc-cursor.h" #include "mongoc-cursor-private.h" #include "mongoc-cursor-cursorid-private.h" #include "mongoc-log.h" #include "mongoc-trace.h" #include "mongoc-error.h" #include "mongoc-util-private.h" #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "cursor-cursorid" static void * _mongoc_cursor_cursorid_new (void) { mongoc_cursor_cursorid_t *cid; ENTRY; cid = (mongoc_cursor_cursorid_t *)bson_malloc0 (sizeof *cid); RETURN (cid); } static void _mongoc_cursor_cursorid_destroy (mongoc_cursor_t *cursor) { ENTRY; bson_free (cursor->iface_data); _mongoc_cursor_destroy (cursor); EXIT; } static bool _mongoc_cursor_cursorid_refresh_from_command (mongoc_cursor_t *cursor, const bson_t *command) { mongoc_cursor_cursorid_t *cid; const bson_t *bson; bson_iter_t iter, child; const char *ns; ENTRY; cid = (mongoc_cursor_cursorid_t *)cursor->iface_data; BSON_ASSERT (cid); /* server replies to find / aggregate with {cursor: {id: N, firstBatch: []}}, * to getMore command with {cursor: {id: N, nextBatch: []}}. */ if (_mongoc_cursor_run_command (cursor, command) && _mongoc_read_from_buffer (cursor, &bson) && bson_iter_init_find (&iter, bson, "cursor") && BSON_ITER_HOLDS_DOCUMENT (&iter) && bson_iter_recurse (&iter, &child)) { while (bson_iter_next (&child)) { if (BSON_ITER_IS_KEY (&child, "id")) { cursor->rpc.reply.cursor_id = bson_iter_as_int64 (&child); } else if (BSON_ITER_IS_KEY (&child, "ns")) { ns = bson_iter_utf8 (&child, &cursor->nslen); bson_strncpy (cursor->ns, ns, sizeof cursor->ns); } else if (BSON_ITER_IS_KEY (&child, "firstBatch") || BSON_ITER_IS_KEY (&child, "nextBatch")) { if (BSON_ITER_HOLDS_ARRAY (&child) && bson_iter_recurse (&child, &cid->batch_iter)) { cid->in_batch = true; } } } RETURN (true); } else { if (!cursor->error.domain) { bson_set_error (&cursor->error, MONGOC_ERROR_PROTOCOL, MONGOC_ERROR_PROTOCOL_INVALID_REPLY, "Invalid reply to %s command.", _mongoc_get_command_name (command)); } RETURN (false); } } static void _mongoc_cursor_cursorid_read_from_batch (mongoc_cursor_t *cursor, const bson_t **bson) { mongoc_cursor_cursorid_t *cid; const uint8_t *data = NULL; uint32_t data_len = 0; ENTRY; cid = (mongoc_cursor_cursorid_t *)cursor->iface_data; BSON_ASSERT (cid); if (bson_iter_next (&cid->batch_iter) && BSON_ITER_HOLDS_DOCUMENT (&cid->batch_iter)) { bson_iter_document (&cid->batch_iter, &data_len, &data); if (bson_init_static (&cid->current_doc, data, data_len)) { *bson = &cid->current_doc; } } } bool _mongoc_cursor_cursorid_prime (mongoc_cursor_t *cursor) { cursor->sent = true; return _mongoc_cursor_cursorid_refresh_from_command (cursor, &cursor->query); } static void _mongoc_cursor_prepare_getmore_command (mongoc_cursor_t *cursor, bson_t *command) { const char *collection; int collection_len; mongoc_cursor_cursorid_t *cid; cid = (mongoc_cursor_cursorid_t *)cursor->iface_data; BSON_ASSERT (cid); _mongoc_cursor_collection (cursor, &collection, &collection_len); bson_init (command); bson_append_int64 (command, "getMore", 7, mongoc_cursor_get_id (cursor)); bson_append_utf8 (command, "collection", 10, collection, collection_len); if (cursor->batch_size) { bson_append_int32 (command, "batchSize", 9, cursor->batch_size); } /* Find, getMore And killCursors Commands Spec: "In the case of a tailable cursor with awaitData == true the driver MUST provide a Cursor level option named maxAwaitTimeMS (See CRUD specification for details). The maxTimeMS option on the getMore command MUST be set to the value of the option maxAwaitTimeMS. If no maxAwaitTimeMS is specified, the driver SHOULD not set maxTimeMS on the getMore command." */ if (cursor->flags & MONGOC_QUERY_TAILABLE_CURSOR && cursor->flags & MONGOC_QUERY_AWAIT_DATA && cursor->max_await_time_ms) { bson_append_int32 (command, "maxTimeMS", 9, cursor->max_await_time_ms); } } static bool _mongoc_cursor_cursorid_get_more (mongoc_cursor_t *cursor) { mongoc_cursor_cursorid_t *cid; mongoc_server_stream_t *server_stream; bson_t command; bool ret; ENTRY; cid = (mongoc_cursor_cursorid_t *)cursor->iface_data; BSON_ASSERT (cid); server_stream = _mongoc_cursor_fetch_stream (cursor); if (!server_stream) { RETURN (false); } if (_use_find_command (cursor, server_stream)) { _mongoc_cursor_prepare_getmore_command (cursor, &command); ret = _mongoc_cursor_cursorid_refresh_from_command (cursor, &command); bson_destroy (&command); } else { ret = _mongoc_cursor_op_getmore (cursor, server_stream); cid->in_reader = ret; } mongoc_server_stream_cleanup (server_stream); RETURN (ret); } bool _mongoc_cursor_cursorid_next (mongoc_cursor_t *cursor, const bson_t **bson) { mongoc_cursor_cursorid_t *cid; bool refreshed = false; ENTRY; *bson = NULL; cid = (mongoc_cursor_cursorid_t *)cursor->iface_data; BSON_ASSERT (cid); if (!cursor->sent) { if (!_mongoc_cursor_cursorid_prime (cursor)) { GOTO (done); } } again: if (cid->in_batch) { _mongoc_cursor_cursorid_read_from_batch (cursor, bson); if (*bson) { GOTO (done); } cid->in_batch = false; } else if (cid->in_reader) { _mongoc_read_from_buffer (cursor, bson); if (*bson) { GOTO (done); } cid->in_reader = false; } if (!refreshed && mongoc_cursor_get_id (cursor)) { if (!_mongoc_cursor_cursorid_get_more (cursor)) { GOTO (done); } refreshed = true; GOTO (again); } done: RETURN (*bson ? true : false); } static mongoc_cursor_t * _mongoc_cursor_cursorid_clone (const mongoc_cursor_t *cursor) { mongoc_cursor_t *clone_; ENTRY; clone_ = _mongoc_cursor_clone (cursor); _mongoc_cursor_cursorid_init (clone_, &cursor->query); RETURN (clone_); } static mongoc_cursor_interface_t gMongocCursorCursorid = { _mongoc_cursor_cursorid_clone, _mongoc_cursor_cursorid_destroy, NULL, _mongoc_cursor_cursorid_next, }; void _mongoc_cursor_cursorid_init (mongoc_cursor_t *cursor, const bson_t *command) { ENTRY; bson_destroy (&cursor->query); bson_copy_to (command, &cursor->query); cursor->iface_data = _mongoc_cursor_cursorid_new (); memcpy (&cursor->iface, &gMongocCursorCursorid, sizeof (mongoc_cursor_interface_t)); EXIT; } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-cursor-private.h0000664000175000017500000001354412673034026024244 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_CURSOR_PRIVATE_H #define MONGOC_CURSOR_PRIVATE_H #if !defined (MONGOC_I_AM_A_DRIVER) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #include #include "mongoc-client.h" #include "mongoc-buffer-private.h" #include "mongoc-rpc-private.h" #include "mongoc-server-stream-private.h" BSON_BEGIN_DECLS typedef struct _mongoc_cursor_interface_t mongoc_cursor_interface_t; struct _mongoc_cursor_interface_t { mongoc_cursor_t *(*clone) (const mongoc_cursor_t *cursor); void (*destroy) (mongoc_cursor_t *cursor); bool (*more) (mongoc_cursor_t *cursor); bool (*next) (mongoc_cursor_t *cursor, const bson_t **bson); bool (*error) (mongoc_cursor_t *cursor, bson_error_t *error); void (*get_host) (mongoc_cursor_t *cursor, mongoc_host_list_t *host); }; struct _mongoc_cursor_t { mongoc_client_t *client; uint32_t hint; uint32_t stamp; unsigned is_command : 1; unsigned sent : 1; unsigned done : 1; unsigned end_of_event : 1; unsigned has_fields : 1; unsigned in_exhaust : 1; bson_t query; bson_t fields; mongoc_read_concern_t *read_concern; mongoc_read_prefs_t *read_prefs; mongoc_query_flags_t flags; uint32_t skip; int32_t limit; uint32_t count; uint32_t batch_size; uint32_t max_await_time_ms; char ns [140]; uint32_t nslen; uint32_t dblen; bson_error_t error; mongoc_rpc_t rpc; mongoc_buffer_t buffer; bson_reader_t *reader; const bson_t *current; mongoc_cursor_interface_t iface; void *iface_data; }; mongoc_cursor_t * _mongoc_cursor_new (mongoc_client_t *client, const char *db_and_collection, mongoc_query_flags_t flags, uint32_t skip, int32_t limit, uint32_t batch_size, bool is_command, const bson_t *query, const bson_t *fields, const mongoc_read_prefs_t *read_prefs, const mongoc_read_concern_t *read_concern); mongoc_cursor_t *_mongoc_cursor_clone (const mongoc_cursor_t *cursor); void _mongoc_cursor_destroy (mongoc_cursor_t *cursor); bool _mongoc_read_from_buffer (mongoc_cursor_t *cursor, const bson_t **bson); bool _use_find_command (const mongoc_cursor_t *cursor, const mongoc_server_stream_t *server_stream); mongoc_server_stream_t * _mongoc_cursor_fetch_stream (mongoc_cursor_t *cursor); void _mongoc_cursor_collection (const mongoc_cursor_t *cursor, const char **collection, int *collection_len); bool _mongoc_cursor_op_getmore (mongoc_cursor_t *cursor, mongoc_server_stream_t *server_stream); bool _mongoc_cursor_run_command (mongoc_cursor_t *cursor, const bson_t *command); bool _mongoc_cursor_more (mongoc_cursor_t *cursor); bool _mongoc_cursor_next (mongoc_cursor_t *cursor, const bson_t **bson); bool _mongoc_cursor_error (mongoc_cursor_t *cursor, bson_error_t *error); void _mongoc_cursor_get_host (mongoc_cursor_t *cursor, mongoc_host_list_t *host); BSON_END_DECLS #endif /* MONGOC_CURSOR_PRIVATE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-cursor-transform-private.h0000664000175000017500000000351412673034026026251 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_CURSOR_FILTER_PRIVATE_H #define MONGOC_CURSOR_FILTER_PRIVATE_H #if !defined (MONGOC_I_AM_A_DRIVER) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #include #include "mongoc-cursor-private.h" BSON_BEGIN_DECLS typedef enum { MONGO_CURSOR_TRANSFORM_DROP, MONGO_CURSOR_TRANSFORM_PASS, MONGO_CURSOR_TRANSFORM_MUTATE, } mongoc_cursor_transform_mode_t; typedef mongoc_cursor_transform_mode_t (*mongoc_cursor_transform_filter_t)(const bson_t *bson, void *ctx); typedef void (*mongoc_cursor_transform_mutate_t)(const bson_t *bson, bson_t *out, void *ctx); typedef void (*mongoc_cursor_transform_dtor_t)(void *ctx); void _mongoc_cursor_transform_init (mongoc_cursor_t *cursor, mongoc_cursor_transform_filter_t filter, mongoc_cursor_transform_mutate_t mutate, mongoc_cursor_transform_dtor_t dtor, void *ctx); BSON_END_DECLS #endif /* MONGOC_CURSOR_FILTER_PRIVATE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-cursor-transform.c0000664000175000017500000001017312673034026024573 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "mongoc-cursor.h" #include "mongoc-cursor-transform-private.h" #include "mongoc-cursor-private.h" #include "mongoc-client-private.h" #include "mongoc-counters-private.h" #include "mongoc-error.h" #include "mongoc-log.h" #include "mongoc-opcode.h" #include "mongoc-trace.h" #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "cursor-transform" typedef struct { mongoc_cursor_transform_filter_t filter; mongoc_cursor_transform_mutate_t mutate; mongoc_cursor_transform_dtor_t dtor; void *ctx; bson_t tmp; } mongoc_cursor_transform_t; static void * _mongoc_cursor_transform_new (mongoc_cursor_transform_filter_t filter, mongoc_cursor_transform_mutate_t mutate, mongoc_cursor_transform_dtor_t dtor, void *ctx) { mongoc_cursor_transform_t *transform; ENTRY; transform = (mongoc_cursor_transform_t *)bson_malloc0 (sizeof *transform); transform->filter = filter; transform->mutate = mutate; transform->dtor = dtor; transform->ctx = ctx; bson_init (&transform->tmp); RETURN (transform); } static void _mongoc_cursor_transform_destroy (mongoc_cursor_t *cursor) { mongoc_cursor_transform_t *transform; ENTRY; transform = (mongoc_cursor_transform_t *)cursor->iface_data; if (transform->dtor) { transform->dtor (transform->ctx); } bson_destroy (&transform->tmp); bson_free (cursor->iface_data); _mongoc_cursor_destroy (cursor); EXIT; } static bool _mongoc_cursor_transform_next (mongoc_cursor_t *cursor, const bson_t **bson) { mongoc_cursor_transform_t *transform; ENTRY; transform = (mongoc_cursor_transform_t *)cursor->iface_data; for (;; ) { if (!_mongoc_cursor_next (cursor, bson)) { RETURN (false); } switch (transform->filter (*bson, transform->ctx)) { case MONGO_CURSOR_TRANSFORM_DROP: break; case MONGO_CURSOR_TRANSFORM_PASS: RETURN (true); break; case MONGO_CURSOR_TRANSFORM_MUTATE: bson_reinit (&transform->tmp); transform->mutate (*bson, &transform->tmp, transform->ctx); *bson = &transform->tmp; RETURN (true); break; default: abort (); break; } } } static mongoc_cursor_t * _mongoc_cursor_transform_clone (const mongoc_cursor_t *cursor) { mongoc_cursor_transform_t *transform; mongoc_cursor_t *clone_; ENTRY; transform = (mongoc_cursor_transform_t *)cursor->iface_data; clone_ = _mongoc_cursor_clone (cursor); _mongoc_cursor_transform_init (clone_, transform->filter, transform->mutate, transform->dtor, transform->ctx); RETURN (clone_); } static mongoc_cursor_interface_t gMongocCursorArray = { _mongoc_cursor_transform_clone, _mongoc_cursor_transform_destroy, NULL, _mongoc_cursor_transform_next, }; void _mongoc_cursor_transform_init (mongoc_cursor_t *cursor, mongoc_cursor_transform_filter_t filter, mongoc_cursor_transform_mutate_t mutate, mongoc_cursor_transform_dtor_t dtor, void *ctx) { ENTRY; cursor->iface_data = _mongoc_cursor_transform_new (filter, mutate, dtor, ctx); memcpy (&cursor->iface, &gMongocCursorArray, sizeof (mongoc_cursor_interface_t)); EXIT; } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-cursor.c0000664000175000017500000010311612673034026022562 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "mongoc-cursor.h" #include "mongoc-cursor-private.h" #include "mongoc-client-private.h" #include "mongoc-counters-private.h" #include "mongoc-error.h" #include "mongoc-log.h" #include "mongoc-trace.h" #include "mongoc-cursor-cursorid-private.h" #include "mongoc-read-concern-private.h" #include "mongoc-util-private.h" #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "cursor" #define CURSOR_FAILED(cursor_) ((cursor_)->error.domain != 0) static const bson_t * _mongoc_cursor_op_query (mongoc_cursor_t *cursor, mongoc_server_stream_t *server_stream); static const bson_t * _mongoc_cursor_find_command (mongoc_cursor_t *cursor); static int32_t _mongoc_n_return (mongoc_cursor_t * cursor) { if (cursor->is_command) { /* commands always have n_return of 1 */ return 1; } else if (cursor->limit < 0) { return cursor->limit; } else if (cursor->limit) { int32_t remaining = cursor->limit - cursor->count; BSON_ASSERT (remaining > 0); if (cursor->batch_size) { return BSON_MIN ((int32_t) cursor->batch_size, remaining); } else { /* batch_size 0 means accept the default */ return remaining; } } else { return cursor->batch_size; } } mongoc_cursor_t * _mongoc_cursor_new (mongoc_client_t *client, const char *db_and_collection, mongoc_query_flags_t qflags, uint32_t skip, int32_t limit, uint32_t batch_size, bool is_command, const bson_t *query, const bson_t *fields, const mongoc_read_prefs_t *read_prefs, const mongoc_read_concern_t *read_concern) { mongoc_cursor_t *cursor; bson_iter_t iter; int flags = qflags; const char *dot; ENTRY; BSON_ASSERT (client); BSON_ASSERT (db_and_collection); if (!read_concern) { read_concern = client->read_concern; } if (!read_prefs) { read_prefs = client->read_prefs; } cursor = (mongoc_cursor_t *)bson_malloc0 (sizeof *cursor); /* * Cursors execute their query lazily. This sadly means that we must copy * some extra data around between the bson_t structures. This should be * small in most cases, so it reduces to a pure memcpy. The benefit to this * design is simplified error handling by API consumers. */ cursor->client = client; bson_strncpy (cursor->ns, db_and_collection, sizeof cursor->ns); cursor->nslen = (uint32_t)bson_strnlen (cursor->ns, sizeof cursor->ns); dot = strstr (db_and_collection, "."); if (dot) { cursor->dblen = (uint32_t)(dot - db_and_collection); } else { /* a database name with no collection name */ cursor->dblen = cursor->nslen; } cursor->flags = (mongoc_query_flags_t)flags; cursor->skip = skip; cursor->limit = limit; cursor->batch_size = batch_size; cursor->is_command = is_command; cursor->has_fields = !!fields; #define MARK_FAILED(c) \ do { \ bson_init (&(c)->query); \ bson_init (&(c)->fields); \ (c)->done = true; \ (c)->end_of_event = true; \ (c)->sent = true; \ } while (0) /* we can't have exhaust queries with limits */ if ((flags & MONGOC_QUERY_EXHAUST) && limit) { bson_set_error (&cursor->error, MONGOC_ERROR_CURSOR, MONGOC_ERROR_CURSOR_INVALID_CURSOR, "Cannot specify MONGOC_QUERY_EXHAUST and set a limit."); MARK_FAILED (cursor); GOTO (finish); } /* we can't have exhaust queries with sharded clusters */ if ((flags & MONGOC_QUERY_EXHAUST) && (client->topology->description.type == MONGOC_TOPOLOGY_SHARDED)) { bson_set_error (&cursor->error, MONGOC_ERROR_CURSOR, MONGOC_ERROR_CURSOR_INVALID_CURSOR, "Cannot specify MONGOC_QUERY_EXHAUST with sharded cluster."); MARK_FAILED (cursor); GOTO (finish); } /* * Check types of various optional parameters. */ if (query && !is_command) { if (bson_iter_init_find (&iter, query, "$explain") && !(BSON_ITER_HOLDS_BOOL (&iter) || BSON_ITER_HOLDS_INT32 (&iter))) { bson_set_error (&cursor->error, MONGOC_ERROR_CURSOR, MONGOC_ERROR_CURSOR_INVALID_CURSOR, "$explain must be a boolean."); MARK_FAILED (cursor); GOTO (finish); } if (bson_iter_init_find (&iter, query, "$snapshot") && !BSON_ITER_HOLDS_BOOL (&iter) && !BSON_ITER_HOLDS_INT32 (&iter)) { bson_set_error (&cursor->error, MONGOC_ERROR_CURSOR, MONGOC_ERROR_CURSOR_INVALID_CURSOR, "$snapshot must be a boolean."); MARK_FAILED (cursor); GOTO (finish); } } /* * Check if we have a mixed top-level query and dollar keys such * as $orderby. This is not allowed (you must use {$query:{}}. */ if (query && bson_iter_init (&iter, query)) { bool found_dollar = false; bool found_non_dollar = false; while (bson_iter_next (&iter)) { if (bson_iter_key (&iter)[0] == '$') { found_dollar = true; } else { found_non_dollar = true; } } if (found_dollar && found_non_dollar) { bson_set_error (&cursor->error, MONGOC_ERROR_CURSOR, MONGOC_ERROR_CURSOR_INVALID_CURSOR, "Cannot mix top-level query with dollar keys such " "as $orderby. Use {$query: {},...} instead."); MARK_FAILED (cursor); GOTO (finish); } } /* don't use MARK_FAILED after this, you'll leak cursor->query */ if (query) { bson_copy_to(query, &cursor->query); } else { bson_init(&cursor->query); } if (fields) { bson_copy_to(fields, &cursor->fields); } else { bson_init(&cursor->fields); } if (read_prefs) { cursor->read_prefs = mongoc_read_prefs_copy (read_prefs); } if (read_concern) { cursor->read_concern = mongoc_read_concern_copy (read_concern); } _mongoc_buffer_init(&cursor->buffer, NULL, 0, NULL, NULL); finish: mongoc_counter_cursors_active_inc(); RETURN (cursor); } void mongoc_cursor_destroy (mongoc_cursor_t *cursor) { ENTRY; BSON_ASSERT(cursor); if (cursor->iface.destroy) { cursor->iface.destroy(cursor); } else { _mongoc_cursor_destroy(cursor); } EXIT; } void _mongoc_cursor_destroy (mongoc_cursor_t *cursor) { char db[MONGOC_NAMESPACE_MAX]; ENTRY; BSON_ASSERT (cursor); if (cursor->in_exhaust) { cursor->client->in_exhaust = false; if (!cursor->done) { /* The only way to stop an exhaust cursor is to kill the connection */ mongoc_cluster_disconnect_node (&cursor->client->cluster, cursor->hint); } } else if (cursor->rpc.reply.cursor_id) { bson_strncpy (db, cursor->ns, cursor->dblen + 1); _mongoc_client_kill_cursor(cursor->client, cursor->hint, cursor->rpc.reply.cursor_id, db, cursor->ns + cursor->dblen + 1); } if (cursor->reader) { bson_reader_destroy(cursor->reader); cursor->reader = NULL; } bson_destroy(&cursor->query); bson_destroy(&cursor->fields); _mongoc_buffer_destroy(&cursor->buffer); mongoc_read_prefs_destroy(cursor->read_prefs); mongoc_read_concern_destroy(cursor->read_concern); bson_free(cursor); mongoc_counter_cursors_active_dec(); mongoc_counter_cursors_disposed_inc(); EXIT; } mongoc_server_stream_t * _mongoc_cursor_fetch_stream (mongoc_cursor_t *cursor) { mongoc_server_stream_t *server_stream; ENTRY; if (cursor->hint) { server_stream = mongoc_cluster_stream_for_server (&cursor->client->cluster, cursor->hint, true /* reconnect_ok */, &cursor->error); } else { server_stream = mongoc_cluster_stream_for_reads (&cursor->client->cluster, cursor->read_prefs, &cursor->error); if (server_stream) { cursor->hint = server_stream->sd->id; } } RETURN (server_stream); } bool _use_find_command (const mongoc_cursor_t *cursor, const mongoc_server_stream_t *server_stream) { /* Find, getMore And killCursors Commands Spec: "the find command cannot be * used to execute other commands" and "the find command does not support the * exhaust flag." */ return server_stream->sd->max_wire_version >= WIRE_VERSION_FIND_CMD && !cursor->is_command && !(cursor->flags & MONGOC_QUERY_EXHAUST); } static const bson_t * _mongoc_cursor_initial_query (mongoc_cursor_t *cursor) { mongoc_server_stream_t *server_stream; const bson_t *b = NULL; ENTRY; BSON_ASSERT (cursor); server_stream = _mongoc_cursor_fetch_stream (cursor); if (!server_stream) { GOTO (done); } if (_use_find_command (cursor, server_stream)) { b = _mongoc_cursor_find_command (cursor); } else { /* When the user explicitly provides a readConcern -- but the server * doesn't support readConcern, we must error: * https://github.com/mongodb/specifications/blob/master/source/read-write-concern/read-write-concern.rst#errors-1 */ if (cursor->read_concern->level != NULL && server_stream->sd->max_wire_version < WIRE_VERSION_READ_CONCERN) { bson_set_error (&cursor->error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, "The selected server does not support readConcern"); } else { b = _mongoc_cursor_op_query (cursor, server_stream); } } done: /* no-op if server_stream is NULL */ mongoc_server_stream_cleanup (server_stream); if (!b) { cursor->done = true; } RETURN (b); } static const bson_t * _mongoc_cursor_op_query (mongoc_cursor_t *cursor, mongoc_server_stream_t *server_stream) { mongoc_apply_read_prefs_result_t result = READ_PREFS_RESULT_INIT; mongoc_rpc_t rpc; uint32_t request_id; const bson_t *bson = NULL; ENTRY; cursor->sent = true; rpc.query.msg_len = 0; rpc.query.request_id = 0; rpc.query.response_to = 0; rpc.query.opcode = MONGOC_OPCODE_QUERY; rpc.query.flags = cursor->flags; rpc.query.collection = cursor->ns; rpc.query.skip = cursor->skip; if ((cursor->flags & MONGOC_QUERY_TAILABLE_CURSOR)) { rpc.query.n_return = 0; } else { rpc.query.n_return = _mongoc_n_return(cursor); } if (cursor->has_fields) { rpc.query.fields = bson_get_data (&cursor->fields); } else { rpc.query.fields = NULL; } apply_read_preferences (cursor->read_prefs, server_stream, &cursor->query, cursor->flags, &result); rpc.query.query = bson_get_data (result.query_with_read_prefs); rpc.query.flags = result.flags; if (!mongoc_cluster_sendv_to_server (&cursor->client->cluster, &rpc, 1, server_stream, NULL, &cursor->error)) { GOTO (failure); } request_id = BSON_UINT32_FROM_LE (rpc.header.request_id); _mongoc_buffer_clear(&cursor->buffer, false); if (!_mongoc_client_recv(cursor->client, &cursor->rpc, &cursor->buffer, server_stream, &cursor->error)) { GOTO (failure); } if (cursor->rpc.header.opcode != MONGOC_OPCODE_REPLY) { bson_set_error (&cursor->error, MONGOC_ERROR_PROTOCOL, MONGOC_ERROR_PROTOCOL_INVALID_REPLY, "Invalid opcode. Expected %d, got %d.", MONGOC_OPCODE_REPLY, cursor->rpc.header.opcode); GOTO (failure); } if (cursor->rpc.header.response_to != request_id) { bson_set_error (&cursor->error, MONGOC_ERROR_PROTOCOL, MONGOC_ERROR_PROTOCOL_INVALID_REPLY, "Invalid response_to for query. Expected %d, got %d.", request_id, cursor->rpc.header.response_to); GOTO (failure); } if (cursor->is_command) { if (_mongoc_rpc_parse_command_error (&cursor->rpc, &cursor->error)) { GOTO (failure); } } else { if (_mongoc_rpc_parse_query_error (&cursor->rpc, &cursor->error)) { GOTO (failure); } } if (cursor->reader) { bson_reader_destroy (cursor->reader); } cursor->reader = bson_reader_new_from_data( cursor->rpc.reply.documents, (size_t) cursor->rpc.reply.documents_len); if ((cursor->flags & MONGOC_QUERY_EXHAUST)) { cursor->in_exhaust = true; cursor->client->in_exhaust = true; } cursor->done = false; cursor->end_of_event = false; cursor->sent = true; _mongoc_read_from_buffer (cursor, &bson); apply_read_prefs_result_cleanup (&result); RETURN (bson); failure: cursor->done = true; apply_read_prefs_result_cleanup (&result); RETURN (false); } bool _mongoc_cursor_run_command (mongoc_cursor_t *cursor, const bson_t *command) { mongoc_cluster_t *cluster; mongoc_server_stream_t *server_stream; char cmd_ns[MONGOC_NAMESPACE_MAX]; mongoc_apply_read_prefs_result_t read_prefs_result = READ_PREFS_RESULT_INIT; bool ret = false; bson_t bson; mongoc_rpc_t rpc; ENTRY; cluster = &cursor->client->cluster; server_stream = _mongoc_cursor_fetch_stream (cursor); if (!server_stream) { GOTO (done); } _mongoc_buffer_clear (&cursor->buffer, false); bson_snprintf (cmd_ns, sizeof cmd_ns, "%.*s.$cmd", cursor->dblen, cursor->ns); apply_read_preferences (cursor->read_prefs, server_stream, command, cursor->flags, &read_prefs_result); _mongoc_rpc_prep_command (&rpc, cmd_ns, read_prefs_result.query_with_read_prefs, read_prefs_result.flags); if (!mongoc_cluster_run_command_rpc (cluster, server_stream->stream, server_stream->sd->id, _mongoc_get_command_name (&cursor->query), &rpc, &cursor->rpc, &cursor->buffer, &cursor->error)) { GOTO (done); } /* static-init "bson" to point into buffer */ if (!_mongoc_rpc_reply_get_first (&cursor->rpc.reply, &bson)) { bson_set_error (&cursor->error, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, "Failed to decode reply BSON document."); GOTO (done); } if (_mongoc_rpc_parse_command_error (&cursor->rpc, &cursor->error)) { GOTO (done); } if (cursor->reader) { bson_reader_destroy (cursor->reader); } cursor->reader = bson_reader_new_from_data ( cursor->rpc.reply.documents, (size_t)cursor->rpc.reply.documents_len); ret = true; done: apply_read_prefs_result_cleanup (&read_prefs_result); mongoc_server_stream_cleanup (server_stream); return ret; } static bool _invalid_field (const char *query_field, mongoc_cursor_t *cursor) { if (query_field[0] == '\0') { bson_set_error (&cursor->error, MONGOC_ERROR_CURSOR, MONGOC_ERROR_CURSOR_INVALID_CURSOR, "empty string is not a valid query operator"); return true; } return false; } static bool _translate_query_opt (const char *query_field, const char **cmd_field, int *len) { if (query_field[0] != '$') { *cmd_field = query_field; *len = -1; return true; } /* strip the leading '$' */ query_field++; if (!strcmp ("query", query_field)) { *cmd_field = "filter"; *len = 6; } else if (!strcmp ("orderby", query_field)) { *cmd_field = "sort"; *len = 4; } else if (!strcmp ("showDiskLoc", query_field)) { /* <= MongoDb 3.0 */ *cmd_field = "showRecordId"; *len = 12; } else if (!strcmp("hint", query_field)) { *cmd_field = "hint"; *len = 4; } else if (!strcmp("comment", query_field)) { *cmd_field = "comment"; *len = 7; } else if (!strcmp("maxScan", query_field)) { *cmd_field = "maxScan"; *len = 7; } else if (!strcmp("maxTimeMS", query_field)) { *cmd_field = "maxTimeMS"; *len = 9; } else if (!strcmp("max", query_field)) { *cmd_field = "max"; *len = 3; } else if (!strcmp("min", query_field)) { *cmd_field = "min"; *len = 3; } else if (!strcmp("returnKey", query_field)) { *cmd_field = "returnKey"; *len = 9; } else if (!strcmp("snapshot", query_field)) { *cmd_field = "snapshot"; *len = 8; } else { /* not a special command field, must be a query operator like $or */ return false; } return true; } static void _mongoc_cursor_prepare_find_command_flags (mongoc_cursor_t *cursor, bson_t *command) { mongoc_query_flags_t flags = cursor->flags; if (flags & MONGOC_QUERY_TAILABLE_CURSOR) { bson_append_bool (command, "tailable", 8, true); } if (flags & MONGOC_QUERY_OPLOG_REPLAY) { bson_append_bool (command, "oplogReplay", 11, true); } if (flags & MONGOC_QUERY_NO_CURSOR_TIMEOUT) { bson_append_bool (command, "noCursorTimeout", 15, true); } if (flags & MONGOC_QUERY_AWAIT_DATA) { bson_append_bool (command, "awaitData", 9, true); } if (flags & MONGOC_QUERY_PARTIAL) { bson_append_bool (command, "allowPartialResults", 19, true); } } void _mongoc_cursor_collection (const mongoc_cursor_t *cursor, const char **collection, int *collection_len) { /* ns is like "db.collection". Collection name is located past the ".". */ *collection = cursor->ns + (cursor->dblen + 1); /* Collection name's length is ns length, minus length of db name and ".". */ *collection_len = cursor->nslen - cursor->dblen - 1; BSON_ASSERT (*collection_len > 0); } static bool _mongoc_cursor_prepare_find_command (mongoc_cursor_t *cursor, bson_t *command) { const char *collection; int collection_len; bson_iter_t iter; const char *command_field; int len; const bson_value_t *value; _mongoc_cursor_collection (cursor, &collection, &collection_len); bson_append_utf8 (command, "find", 4, collection, collection_len); if (bson_empty0 (&cursor->query)) { /* Find, getMore And killCursors Commands Spec: filter "MUST be included * in the command". */ bson_t empty = BSON_INITIALIZER; bson_append_document (command, "filter", 6, &empty); } else if (bson_has_field (&cursor->query, "$query")) { bson_iter_init (&iter, &cursor->query); while (bson_iter_next (&iter)) { if (_invalid_field (bson_iter_key (&iter), cursor)) { return false; } value = bson_iter_value (&iter); if (_translate_query_opt (bson_iter_key (&iter), &command_field, &len)) { bson_append_value (command, command_field, len, value); } else { bson_append_value (command, bson_iter_key (&iter), -1, value); } } } else if (bson_has_field (&cursor->query, "filter")) { bson_concat (command, &cursor->query); } else { /* cursor->query has no "$query", use it as the filter */ bson_append_document (command, "filter", 6, &cursor->query); } if (!bson_empty0 (&cursor->fields)) { bson_append_document (command, "projection", 10, &cursor->fields); } if (cursor->skip) { bson_append_int64 (command, "skip", 4, cursor->skip); } if (cursor->limit) { if (cursor->limit < 0) { bson_append_bool (command, "singleBatch", 11, true); } bson_append_int64 (command, "limit", 5, labs(cursor->limit)); } if (cursor->batch_size) { bson_append_int32 (command, "batchSize", 9, cursor->batch_size); } if (cursor->read_concern->level != NULL) { const bson_t *read_concern_bson; read_concern_bson = _mongoc_read_concern_get_bson (cursor->read_concern); BSON_APPEND_DOCUMENT (command, "readConcern", read_concern_bson); } _mongoc_cursor_prepare_find_command_flags (cursor, command); return true; } static const bson_t * _mongoc_cursor_find_command (mongoc_cursor_t *cursor) { bson_t command = BSON_INITIALIZER; const bson_t *bson = NULL; ENTRY; if (!_mongoc_cursor_prepare_find_command (cursor, &command)) { RETURN (NULL); } _mongoc_cursor_cursorid_init (cursor, &command); bson_destroy (&command); BSON_ASSERT (cursor->iface.next); _mongoc_cursor_cursorid_next (cursor, &bson); RETURN (bson); } static const bson_t * _mongoc_cursor_get_more (mongoc_cursor_t *cursor) { mongoc_server_stream_t *server_stream; const bson_t *b = NULL; ENTRY; BSON_ASSERT (cursor); server_stream = _mongoc_cursor_fetch_stream (cursor); if (!server_stream) { GOTO (failure); } if (!cursor->in_exhaust && !cursor->rpc.reply.cursor_id) { bson_set_error (&cursor->error, MONGOC_ERROR_CURSOR, MONGOC_ERROR_CURSOR_INVALID_CURSOR, "No valid cursor was provided."); GOTO (failure); } if (!_mongoc_cursor_op_getmore (cursor, server_stream)) { GOTO (failure); } mongoc_server_stream_cleanup (server_stream); if (cursor->reader) { _mongoc_read_from_buffer (cursor, &b); } RETURN (b); failure: cursor->done = true; mongoc_server_stream_cleanup (server_stream); RETURN (NULL); } bool _mongoc_cursor_op_getmore (mongoc_cursor_t *cursor, mongoc_server_stream_t *server_stream) { mongoc_rpc_t rpc; uint32_t request_id; bool ret = false; ENTRY; if (cursor->in_exhaust) { request_id = (uint32_t) cursor->rpc.header.request_id; } else { rpc.get_more.cursor_id = cursor->rpc.reply.cursor_id; rpc.get_more.msg_len = 0; rpc.get_more.request_id = 0; rpc.get_more.response_to = 0; rpc.get_more.opcode = MONGOC_OPCODE_GET_MORE; rpc.get_more.zero = 0; rpc.get_more.collection = cursor->ns; if ((cursor->flags & MONGOC_QUERY_TAILABLE_CURSOR)) { rpc.get_more.n_return = 0; } else { rpc.get_more.n_return = _mongoc_n_return(cursor); } if (!mongoc_cluster_sendv_to_server (&cursor->client->cluster, &rpc, 1, server_stream, NULL, &cursor->error)) { GOTO (done); } request_id = BSON_UINT32_FROM_LE (rpc.header.request_id); } _mongoc_buffer_clear (&cursor->buffer, false); if (!_mongoc_client_recv (cursor->client, &cursor->rpc, &cursor->buffer, server_stream, &cursor->error)) { GOTO (done); } if (cursor->rpc.header.opcode != MONGOC_OPCODE_REPLY) { bson_set_error (&cursor->error, MONGOC_ERROR_PROTOCOL, MONGOC_ERROR_PROTOCOL_INVALID_REPLY, "Invalid opcode. Expected %d, got %d.", MONGOC_OPCODE_REPLY, cursor->rpc.header.opcode); GOTO (done); } if (cursor->rpc.header.response_to != request_id) { bson_set_error (&cursor->error, MONGOC_ERROR_PROTOCOL, MONGOC_ERROR_PROTOCOL_INVALID_REPLY, "Invalid response_to for getmore. Expected %d, got %d.", request_id, cursor->rpc.header.response_to); GOTO (done); } if (_mongoc_rpc_parse_query_error (&cursor->rpc, &cursor->error)) { GOTO (done); } if (cursor->reader) { bson_reader_destroy (cursor->reader); } cursor->reader = bson_reader_new_from_data ( cursor->rpc.reply.documents, (size_t)cursor->rpc.reply.documents_len); ret = true; done: RETURN (ret); } bool mongoc_cursor_error (mongoc_cursor_t *cursor, bson_error_t *error) { bool ret; ENTRY; BSON_ASSERT(cursor); if (cursor->iface.error) { ret = cursor->iface.error(cursor, error); } else { ret = _mongoc_cursor_error(cursor, error); } RETURN(ret); } bool _mongoc_cursor_error (mongoc_cursor_t *cursor, bson_error_t *error) { ENTRY; BSON_ASSERT (cursor); if (BSON_UNLIKELY(CURSOR_FAILED (cursor))) { bson_set_error(error, cursor->error.domain, cursor->error.code, "%s", cursor->error.message); RETURN(true); } RETURN(false); } bool mongoc_cursor_next (mongoc_cursor_t *cursor, const bson_t **bson) { bool ret; ENTRY; BSON_ASSERT(cursor); BSON_ASSERT(bson); TRACE ("cursor_id(%"PRId64")", cursor->rpc.reply.cursor_id); if (bson) { *bson = NULL; } if (CURSOR_FAILED (cursor)) { return false; } /* * We cannot proceed if another cursor is receiving results in exhaust mode. */ if (cursor->client->in_exhaust && !cursor->in_exhaust) { bson_set_error (&cursor->error, MONGOC_ERROR_CLIENT, MONGOC_ERROR_CLIENT_IN_EXHAUST, "Another cursor derived from this client is in exhaust."); RETURN (false); } if (cursor->iface.next) { ret = cursor->iface.next(cursor, bson); } else { ret = _mongoc_cursor_next(cursor, bson); } cursor->current = *bson; cursor->count++; RETURN(ret); } bool _mongoc_read_from_buffer (mongoc_cursor_t *cursor, const bson_t **bson) { bool eof = false; BSON_ASSERT (cursor->reader); *bson = bson_reader_read (cursor->reader, &eof); cursor->end_of_event = eof ? 1 : 0; return *bson ? true : false; } bool _mongoc_cursor_next (mongoc_cursor_t *cursor, const bson_t **bson) { const bson_t *b = NULL; ENTRY; BSON_ASSERT (cursor); if (bson) { *bson = NULL; } if (cursor->done || CURSOR_FAILED (cursor)) { bson_set_error (&cursor->error, MONGOC_ERROR_CURSOR, MONGOC_ERROR_CURSOR_INVALID_CURSOR, "Cannot advance a completed or failed cursor."); RETURN (false); } /* * If we reached our limit, make sure we mark this as done and do not try to * make further progress. */ if (cursor->limit && cursor->count >= labs(cursor->limit)) { cursor->done = true; RETURN (false); } /* * Try to read the next document from the reader if it exists, we might * get NULL back and EOF, in which case we need to submit a getmore. */ if (cursor->reader) { _mongoc_read_from_buffer (cursor, &b); if (b) { GOTO (complete); } } /* * Check to see if we need to send a GET_MORE for more results. */ if (!cursor->sent) { b = _mongoc_cursor_initial_query (cursor); } else if (BSON_UNLIKELY (cursor->end_of_event) && cursor->rpc.reply.cursor_id) { b = _mongoc_cursor_get_more (cursor); } complete: cursor->done = (cursor->end_of_event && ((cursor->in_exhaust && !cursor->rpc.reply.cursor_id) || (!b && !(cursor->flags & MONGOC_QUERY_TAILABLE_CURSOR)))); if (bson) { *bson = b; } RETURN (!!b); } bool mongoc_cursor_more (mongoc_cursor_t *cursor) { bool ret; ENTRY; BSON_ASSERT(cursor); if (cursor->iface.more) { ret = cursor->iface.more(cursor); } else { ret = _mongoc_cursor_more(cursor); } RETURN(ret); } bool _mongoc_cursor_more (mongoc_cursor_t *cursor) { BSON_ASSERT (cursor); if (CURSOR_FAILED (cursor)) { return false; } return (!cursor->sent || cursor->rpc.reply.cursor_id || !cursor->end_of_event); } void mongoc_cursor_get_host (mongoc_cursor_t *cursor, mongoc_host_list_t *host) { BSON_ASSERT(cursor); BSON_ASSERT(host); if (cursor->iface.get_host) { cursor->iface.get_host(cursor, host); } else { _mongoc_cursor_get_host(cursor, host); } EXIT; } void _mongoc_cursor_get_host (mongoc_cursor_t *cursor, mongoc_host_list_t *host) { mongoc_server_description_t *description; BSON_ASSERT (cursor); BSON_ASSERT (host); memset(host, 0, sizeof *host); if (!cursor->hint) { MONGOC_WARNING("%s(): Must send query before fetching peer.", BSON_FUNC); return; } description = mongoc_topology_server_by_id(cursor->client->topology, cursor->hint, &cursor->error); if (!description) { return; } *host = description->host; mongoc_server_description_destroy (description); return; } mongoc_cursor_t * mongoc_cursor_clone (const mongoc_cursor_t *cursor) { mongoc_cursor_t *ret; BSON_ASSERT(cursor); if (cursor->iface.clone) { ret = cursor->iface.clone(cursor); } else { ret = _mongoc_cursor_clone(cursor); } RETURN(ret); } mongoc_cursor_t * _mongoc_cursor_clone (const mongoc_cursor_t *cursor) { mongoc_cursor_t *_clone; ENTRY; BSON_ASSERT (cursor); _clone = (mongoc_cursor_t *)bson_malloc0 (sizeof *_clone); _clone->client = cursor->client; _clone->is_command = cursor->is_command; _clone->flags = cursor->flags; _clone->skip = cursor->skip; _clone->batch_size = cursor->batch_size; _clone->limit = cursor->limit; _clone->nslen = cursor->nslen; _clone->dblen = cursor->dblen; _clone->has_fields = cursor->has_fields; if (cursor->read_prefs) { _clone->read_prefs = mongoc_read_prefs_copy (cursor->read_prefs); } if (cursor->read_concern) { _clone->read_concern = mongoc_read_concern_copy (cursor->read_concern); } bson_copy_to (&cursor->query, &_clone->query); bson_copy_to (&cursor->fields, &_clone->fields); bson_strncpy (_clone->ns, cursor->ns, sizeof _clone->ns); _mongoc_buffer_init (&_clone->buffer, NULL, 0, NULL, NULL); mongoc_counter_cursors_active_inc (); RETURN (_clone); } /* *-------------------------------------------------------------------------- * * mongoc_cursor_is_alive -- * * Checks to see if a cursor is alive. * * This is primarily useful with tailable cursors. * * Returns: * true if the cursor is alive. * * Side effects: * None. * *-------------------------------------------------------------------------- */ bool mongoc_cursor_is_alive (const mongoc_cursor_t *cursor) /* IN */ { BSON_ASSERT (cursor); return (!cursor->sent || (!CURSOR_FAILED (cursor) && !cursor->done && (cursor->rpc.header.opcode == MONGOC_OPCODE_REPLY) && cursor->rpc.reply.cursor_id)); } const bson_t * mongoc_cursor_current (const mongoc_cursor_t *cursor) /* IN */ { BSON_ASSERT (cursor); return cursor->current; } void mongoc_cursor_set_batch_size (mongoc_cursor_t *cursor, uint32_t batch_size) { BSON_ASSERT (cursor); cursor->batch_size = batch_size; } uint32_t mongoc_cursor_get_batch_size (const mongoc_cursor_t *cursor) { BSON_ASSERT (cursor); return cursor->batch_size; } uint32_t mongoc_cursor_get_hint (const mongoc_cursor_t *cursor) { BSON_ASSERT (cursor); return cursor->hint; } int64_t mongoc_cursor_get_id (const mongoc_cursor_t *cursor) { BSON_ASSERT(cursor); return cursor->rpc.reply.cursor_id; } void mongoc_cursor_set_max_await_time_ms (mongoc_cursor_t *cursor, uint32_t max_await_time_ms) { BSON_ASSERT (cursor); if (!cursor->sent) { cursor->max_await_time_ms = max_await_time_ms; } } uint32_t mongoc_cursor_get_max_await_time_ms (const mongoc_cursor_t *cursor) { BSON_ASSERT (cursor); return cursor->max_await_time_ms; } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-cursor.h0000664000175000017500000000505412673034026022571 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_CURSOR_H #define MONGOC_CURSOR_H #if !defined (MONGOC_INSIDE) && !defined (MONGOC_COMPILATION) # error "Only can be included directly." #endif #include #include "mongoc-host-list.h" BSON_BEGIN_DECLS typedef struct _mongoc_cursor_t mongoc_cursor_t; mongoc_cursor_t *mongoc_cursor_clone (const mongoc_cursor_t *cursor) BSON_GNUC_WARN_UNUSED_RESULT; void mongoc_cursor_destroy (mongoc_cursor_t *cursor); bool mongoc_cursor_more (mongoc_cursor_t *cursor); bool mongoc_cursor_next (mongoc_cursor_t *cursor, const bson_t **bson); bool mongoc_cursor_error (mongoc_cursor_t *cursor, bson_error_t *error); void mongoc_cursor_get_host (mongoc_cursor_t *cursor, mongoc_host_list_t *host); bool mongoc_cursor_is_alive (const mongoc_cursor_t *cursor); const bson_t *mongoc_cursor_current (const mongoc_cursor_t *cursor); void mongoc_cursor_set_batch_size (mongoc_cursor_t *cursor, uint32_t batch_size); uint32_t mongoc_cursor_get_batch_size (const mongoc_cursor_t *cursor); uint32_t mongoc_cursor_get_hint (const mongoc_cursor_t *cursor); int64_t mongoc_cursor_get_id (const mongoc_cursor_t *cursor); void mongoc_cursor_set_max_await_time_ms (mongoc_cursor_t *cursor, uint32_t max_await_time_ms); uint32_t mongoc_cursor_get_max_await_time_ms (const mongoc_cursor_t *cursor); BSON_END_DECLS #endif /* MONGOC_CURSOR_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-database-private.h0000664000175000017500000000404712673034026024471 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_DATABASE_PRIVATE_H #define MONGOC_DATABASE_PRIVATE_H #if !defined (MONGOC_I_AM_A_DRIVER) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #include #include "mongoc-client.h" #include "mongoc-read-prefs.h" #include "mongoc-read-concern.h" #include "mongoc-write-concern.h" BSON_BEGIN_DECLS struct _mongoc_database_t { mongoc_client_t *client; char name [128]; mongoc_read_prefs_t *read_prefs; mongoc_read_concern_t *read_concern; mongoc_write_concern_t *write_concern; }; mongoc_database_t *_mongoc_database_new (mongoc_client_t *client, const char *name, const mongoc_read_prefs_t *read_prefs, const mongoc_read_concern_t *read_concern, const mongoc_write_concern_t *write_concern); mongoc_cursor_t *_mongoc_database_find_collections_legacy (mongoc_database_t *database, const bson_t *filter, bson_error_t *error); BSON_END_DECLS #endif /* MONGOC_DATABASE_PRIVATE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-database.c0000664000175000017500000007755512673034026023032 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "mongoc-client-private.h" #include "mongoc-collection.h" #include "mongoc-collection-private.h" #include "mongoc-cursor.h" #include "mongoc-cursor-array-private.h" #include "mongoc-cursor-cursorid-private.h" #include "mongoc-cursor-transform-private.h" #include "mongoc-cursor-private.h" #include "mongoc-database.h" #include "mongoc-database-private.h" #include "mongoc-error.h" #include "mongoc-log.h" #include "mongoc-trace.h" #include "mongoc-util-private.h" #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "database" /* *-------------------------------------------------------------------------- * * _mongoc_database_new -- * * Create a new instance of mongoc_database_t for @client. * * @client must stay valid for the life of the resulting * database structure. * * Returns: * A newly allocated mongoc_database_t that should be freed with * mongoc_database_destroy(). * * Side effects: * None. * *-------------------------------------------------------------------------- */ mongoc_database_t * _mongoc_database_new (mongoc_client_t *client, const char *name, const mongoc_read_prefs_t *read_prefs, const mongoc_read_concern_t *read_concern, const mongoc_write_concern_t *write_concern) { mongoc_database_t *db; ENTRY; BSON_ASSERT (client); BSON_ASSERT (name); db = (mongoc_database_t *)bson_malloc0(sizeof *db); db->client = client; db->write_concern = write_concern ? mongoc_write_concern_copy(write_concern) : mongoc_write_concern_new(); db->read_concern = read_concern ? mongoc_read_concern_copy(read_concern) : mongoc_read_concern_new(); db->read_prefs = read_prefs ? mongoc_read_prefs_copy(read_prefs) : mongoc_read_prefs_new(MONGOC_READ_PRIMARY); bson_strncpy (db->name, name, sizeof db->name); RETURN(db); } /* *-------------------------------------------------------------------------- * * mongoc_database_destroy -- * * Releases resources associated with @database. * * Returns: * None. * * Side effects: * Everything. * *-------------------------------------------------------------------------- */ void mongoc_database_destroy (mongoc_database_t *database) { ENTRY; BSON_ASSERT (database); if (database->read_prefs) { mongoc_read_prefs_destroy(database->read_prefs); database->read_prefs = NULL; } if (database->read_concern) { mongoc_read_concern_destroy(database->read_concern); database->read_concern = NULL; } if (database->write_concern) { mongoc_write_concern_destroy(database->write_concern); database->write_concern = NULL; } bson_free(database); EXIT; } /* *-------------------------------------------------------------------------- * * mongoc_database_copy -- * * Returns a copy of @database that needs to be freed by calling * mongoc_database_destroy. * * Returns: * A copy of this database. * * Side effects: * None. * *-------------------------------------------------------------------------- */ mongoc_database_t * mongoc_database_copy (mongoc_database_t *database) { ENTRY; BSON_ASSERT (database); RETURN(_mongoc_database_new(database->client, database->name, database->read_prefs, database->read_concern, database->write_concern)); } mongoc_cursor_t * mongoc_database_command (mongoc_database_t *database, mongoc_query_flags_t flags, uint32_t skip, uint32_t limit, uint32_t batch_size, const bson_t *command, const bson_t *fields, const mongoc_read_prefs_t *read_prefs) { BSON_ASSERT (database); BSON_ASSERT (command); if (!read_prefs) { read_prefs = database->read_prefs; } return mongoc_client_command (database->client, database->name, flags, skip, limit, batch_size, command, fields, read_prefs); } bool mongoc_database_command_simple (mongoc_database_t *database, const bson_t *command, const mongoc_read_prefs_t *read_prefs, bson_t *reply, bson_error_t *error) { BSON_ASSERT (database); BSON_ASSERT (command); if (!read_prefs) { read_prefs = database->read_prefs; } return mongoc_client_command_simple (database->client, database->name, command, read_prefs, reply, error); } /* *-------------------------------------------------------------------------- * * mongoc_database_drop -- * * Requests that the MongoDB server drops @database, including all * collections and indexes associated with @database. * * Make sure this is really what you want! * * Returns: * true if @database was dropped. * * Side effects: * @error may be set. * *-------------------------------------------------------------------------- */ bool mongoc_database_drop (mongoc_database_t *database, bson_error_t *error) { bool ret; bson_t cmd; BSON_ASSERT (database); bson_init(&cmd); bson_append_int32(&cmd, "dropDatabase", 12, 1); ret = mongoc_database_command_simple(database, &cmd, NULL, NULL, error); bson_destroy(&cmd); return ret; } /* *-------------------------------------------------------------------------- * * mongoc_database_add_user_legacy -- * * A helper to add a user or update their password on @database. * This uses the legacy protocol by inserting into system.users. * * Returns: * true if successful; otherwise false and @error is set. * * Side effects: * @error may be set. * *-------------------------------------------------------------------------- */ static bool mongoc_database_add_user_legacy (mongoc_database_t *database, const char *username, const char *password, bson_error_t *error) { mongoc_collection_t *collection; mongoc_cursor_t *cursor = NULL; const bson_t *doc; bool ret = false; bson_t query; bson_t user; char *input; char *pwd = NULL; ENTRY; BSON_ASSERT (database); BSON_ASSERT (username); BSON_ASSERT (password); /* * Users are stored in the .system.users virtual collection. */ collection = mongoc_client_get_collection(database->client, database->name, "system.users"); BSON_ASSERT(collection); /* * Hash the users password. */ input = bson_strdup_printf("%s:mongo:%s", username, password); pwd = _mongoc_hex_md5(input); bson_free(input); /* * Check to see if the user exists. If so, we will update the * password instead of inserting a new user. */ bson_init(&query); bson_append_utf8(&query, "user", 4, username, -1); cursor = mongoc_collection_find(collection, MONGOC_QUERY_NONE, 0, 1, 0, &query, NULL, NULL); if (!mongoc_cursor_next(cursor, &doc)) { if (mongoc_cursor_error(cursor, error)) { GOTO (failure); } bson_init(&user); bson_append_utf8(&user, "user", 4, username, -1); bson_append_bool(&user, "readOnly", 8, false); bson_append_utf8(&user, "pwd", 3, pwd, -1); } else { bson_init(&user); bson_copy_to_excluding_noinit(doc, &user, "pwd", (char *)NULL); bson_append_utf8(&user, "pwd", 3, pwd, -1); } if (!mongoc_collection_save(collection, &user, NULL, error)) { GOTO (failure_with_user); } ret = true; failure_with_user: bson_destroy(&user); failure: if (cursor) { mongoc_cursor_destroy(cursor); } mongoc_collection_destroy(collection); bson_destroy(&query); bson_free(pwd); RETURN (ret); } bool mongoc_database_remove_user (mongoc_database_t *database, const char *username, bson_error_t *error) { mongoc_collection_t *col; bson_error_t lerror; bson_t cmd; bool ret; ENTRY; BSON_ASSERT (database); BSON_ASSERT (username); bson_init (&cmd); BSON_APPEND_UTF8 (&cmd, "dropUser", username); ret = mongoc_database_command_simple (database, &cmd, NULL, NULL, &lerror); bson_destroy (&cmd); if (!ret && (lerror.code == MONGOC_ERROR_QUERY_COMMAND_NOT_FOUND)) { bson_init (&cmd); BSON_APPEND_UTF8 (&cmd, "user", username); col = mongoc_client_get_collection (database->client, database->name, "system.users"); BSON_ASSERT (col); ret = mongoc_collection_remove (col, MONGOC_REMOVE_SINGLE_REMOVE, &cmd, NULL, error); bson_destroy (&cmd); mongoc_collection_destroy (col); } else if (error) { memcpy (error, &lerror, sizeof *error); } RETURN (ret); } bool mongoc_database_remove_all_users (mongoc_database_t *database, bson_error_t *error) { mongoc_collection_t *col; bson_error_t lerror; bson_t cmd; bool ret; ENTRY; BSON_ASSERT (database); bson_init (&cmd); BSON_APPEND_INT32 (&cmd, "dropAllUsersFromDatabase", 1); ret = mongoc_database_command_simple (database, &cmd, NULL, NULL, &lerror); bson_destroy (&cmd); if (!ret && (lerror.code == MONGOC_ERROR_QUERY_COMMAND_NOT_FOUND)) { bson_init (&cmd); col = mongoc_client_get_collection (database->client, database->name, "system.users"); BSON_ASSERT (col); ret = mongoc_collection_remove (col, MONGOC_REMOVE_NONE, &cmd, NULL, error); bson_destroy (&cmd); mongoc_collection_destroy (col); } else if (error) { memcpy (error, &lerror, sizeof *error); } RETURN (ret); } /** * mongoc_database_add_user: * @database: A #mongoc_database_t. * @username: A string containing the username. * @password: (allow-none): A string containing password, or NULL. * @roles: (allow-none): An optional bson_t of roles. * @custom_data: (allow-none): An optional bson_t of data to store. * @error: (out) (allow-none): A location for a bson_error_t or %NULL. * * Creates a new user with access to @database. * * Returns: None. * Side effects: None. */ bool mongoc_database_add_user (mongoc_database_t *database, const char *username, const char *password, const bson_t *roles, const bson_t *custom_data, bson_error_t *error) { bson_error_t lerror; bson_t cmd; bson_t ar; char *input; char *hashed_password; bool ret = false; ENTRY; BSON_ASSERT (database); BSON_ASSERT (username); /* * CDRIVER-232: * * Perform a (slow and tedious) round trip to mongod to determine if * we can safely call createUser. Otherwise, we will fallback and * perform legacy insertion into users collection. */ bson_init (&cmd); BSON_APPEND_UTF8 (&cmd, "usersInfo", username); ret = mongoc_database_command_simple (database, &cmd, NULL, NULL, &lerror); bson_destroy (&cmd); if (!ret && (lerror.code == MONGOC_ERROR_QUERY_COMMAND_NOT_FOUND)) { ret = mongoc_database_add_user_legacy (database, username, password, error); } else if (ret || (lerror.code == 13)) { /* usersInfo succeeded or failed with auth err, we're on modern mongod */ input = bson_strdup_printf ("%s:mongo:%s", username, password); hashed_password = _mongoc_hex_md5 (input); bson_free (input); bson_init (&cmd); BSON_APPEND_UTF8 (&cmd, "createUser", username); BSON_APPEND_UTF8 (&cmd, "pwd", hashed_password); BSON_APPEND_BOOL (&cmd, "digestPassword", false); if (custom_data) { BSON_APPEND_DOCUMENT (&cmd, "customData", custom_data); } if (roles) { BSON_APPEND_ARRAY (&cmd, "roles", roles); } else { bson_append_array_begin (&cmd, "roles", 5, &ar); bson_append_array_end (&cmd, &ar); } ret = mongoc_database_command_simple (database, &cmd, NULL, NULL, error); bson_free (hashed_password); bson_destroy (&cmd); } else if (error) { memcpy (error, &lerror, sizeof *error); } RETURN (ret); } /* *-------------------------------------------------------------------------- * * mongoc_database_get_read_prefs -- * * Fetch the read preferences for @database. * * Returns: * A mongoc_read_prefs_t that should not be modified or freed. * * Side effects: * None. * *-------------------------------------------------------------------------- */ const mongoc_read_prefs_t * mongoc_database_get_read_prefs (const mongoc_database_t *database) /* IN */ { BSON_ASSERT (database); return database->read_prefs; } /* *-------------------------------------------------------------------------- * * mongoc_database_set_read_prefs -- * * Sets the default read preferences for @database. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void mongoc_database_set_read_prefs (mongoc_database_t *database, const mongoc_read_prefs_t *read_prefs) { BSON_ASSERT (database); if (database->read_prefs) { mongoc_read_prefs_destroy(database->read_prefs); database->read_prefs = NULL; } if (read_prefs) { database->read_prefs = mongoc_read_prefs_copy(read_prefs); } } /* *-------------------------------------------------------------------------- * * mongoc_database_get_read_concern -- * * Fetches the read concern for @database. * * Returns: * A mongoc_read_concern_t that should not be modified or freed. * * Side effects: * None. * *-------------------------------------------------------------------------- */ const mongoc_read_concern_t * mongoc_database_get_read_concern (const mongoc_database_t *database) { BSON_ASSERT (database); return database->read_concern; } /* *-------------------------------------------------------------------------- * * mongoc_database_set_read_concern -- * * Set the default read concern for @database. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void mongoc_database_set_read_concern (mongoc_database_t *database, const mongoc_read_concern_t *read_concern) { BSON_ASSERT (database); if (database->read_concern) { mongoc_read_concern_destroy (database->read_concern); database->read_concern = NULL; } if (read_concern) { database->read_concern = mongoc_read_concern_copy (read_concern); } } /* *-------------------------------------------------------------------------- * * mongoc_database_get_write_concern -- * * Fetches the write concern for @database. * * Returns: * A mongoc_write_concern_t that should not be modified or freed. * * Side effects: * None. * *-------------------------------------------------------------------------- */ const mongoc_write_concern_t * mongoc_database_get_write_concern (const mongoc_database_t *database) { BSON_ASSERT (database); return database->write_concern; } /* *-------------------------------------------------------------------------- * * mongoc_database_set_write_concern -- * * Set the default write concern for @database. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void mongoc_database_set_write_concern (mongoc_database_t *database, const mongoc_write_concern_t *write_concern) { BSON_ASSERT (database); if (database->write_concern) { mongoc_write_concern_destroy(database->write_concern); database->write_concern = NULL; } if (write_concern) { database->write_concern = mongoc_write_concern_copy(write_concern); } } /** * mongoc_database_has_collection: * @database: (in): A #mongoc_database_t. * @name: (in): The name of the collection to check for. * @error: (out) (allow-none): A location for a #bson_error_t, or %NULL. * * Checks to see if a collection exists within the database on the MongoDB * server. * * This will return %false if their was an error communicating with the * server, or if the collection does not exist. * * If @error is provided, it will first be zeroed. Upon error, error.domain * will be set. * * Returns: %true if @name exists, otherwise %false. @error may be set. */ bool mongoc_database_has_collection (mongoc_database_t *database, const char *name, bson_error_t *error) { bson_iter_t col_iter; bool ret = false; const char *cur_name; bson_t filter = BSON_INITIALIZER; mongoc_cursor_t *cursor; const bson_t *doc; ENTRY; BSON_ASSERT (database); BSON_ASSERT (name); if (error) { memset (error, 0, sizeof *error); } BSON_APPEND_UTF8 (&filter, "name", name); cursor = mongoc_database_find_collections (database, &filter, error); if (!cursor) { return ret; } if (error && ((error->domain != 0) || (error->code != 0))) { GOTO (cleanup); } while (mongoc_cursor_next (cursor, &doc)) { if (bson_iter_init (&col_iter, doc) && bson_iter_find (&col_iter, "name") && BSON_ITER_HOLDS_UTF8 (&col_iter) && (cur_name = bson_iter_utf8 (&col_iter, NULL))) { if (!strcmp (cur_name, name)) { ret = true; GOTO (cleanup); } } } cleanup: mongoc_cursor_destroy (cursor); RETURN (ret); } typedef struct { const char *dbname; size_t dbname_len; const char *name; } mongoc_database_find_collections_legacy_ctx_t; static mongoc_cursor_transform_mode_t _mongoc_database_find_collections_legacy_filter (const bson_t *bson, void *ctx_) { bson_iter_t iter; mongoc_database_find_collections_legacy_ctx_t *ctx; ctx = (mongoc_database_find_collections_legacy_ctx_t *)ctx_; if (bson_iter_init_find (&iter, bson, "name") && BSON_ITER_HOLDS_UTF8 (&iter) && (ctx->name = bson_iter_utf8 (&iter, NULL)) && !strchr (ctx->name, '$') && (0 == strncmp (ctx->name, ctx->dbname, ctx->dbname_len))) { return MONGO_CURSOR_TRANSFORM_MUTATE; } else { return MONGO_CURSOR_TRANSFORM_DROP; } } static void _mongoc_database_find_collections_legacy_mutate (const bson_t *bson, bson_t *out, void *ctx_) { mongoc_database_find_collections_legacy_ctx_t *ctx; ctx = (mongoc_database_find_collections_legacy_ctx_t *)ctx_; bson_copy_to_excluding_noinit (bson, out, "name", NULL); BSON_APPEND_UTF8 (out, "name", ctx->name + (ctx->dbname_len + 1)); /* +1 for the '.' */ } /* Uses old way of querying system.namespaces. */ mongoc_cursor_t * _mongoc_database_find_collections_legacy (mongoc_database_t *database, const bson_t *filter, bson_error_t *error) { mongoc_collection_t *col; mongoc_cursor_t *cursor = NULL; mongoc_read_prefs_t *read_prefs; uint32_t dbname_len; bson_t legacy_filter; bson_iter_t iter; const char *col_filter; bson_t q = BSON_INITIALIZER; mongoc_database_find_collections_legacy_ctx_t *ctx; BSON_ASSERT (database); col = mongoc_client_get_collection (database->client, database->name, "system.namespaces"); BSON_ASSERT (col); dbname_len = (uint32_t)strlen (database->name); ctx = (mongoc_database_find_collections_legacy_ctx_t *)bson_malloc (sizeof (*ctx)); ctx->dbname = database->name; ctx->dbname_len = dbname_len; /* Filtering on name needs to be handled differently for old servers. */ if (filter && bson_iter_init_find (&iter, filter, "name")) { bson_string_t *buf; /* on legacy servers, this must be a string (i.e. not a regex) */ if (!BSON_ITER_HOLDS_UTF8 (&iter)) { bson_set_error (error, MONGOC_ERROR_NAMESPACE, MONGOC_ERROR_NAMESPACE_INVALID_FILTER_TYPE, "On legacy servers, a filter on name can only be a string."); bson_free (ctx); goto cleanup_filter; } BSON_ASSERT (BSON_ITER_HOLDS_UTF8 (&iter)); col_filter = bson_iter_utf8 (&iter, NULL); bson_init (&legacy_filter); bson_copy_to_excluding_noinit (filter, &legacy_filter, "name", NULL); /* We must db-qualify filters on name. */ buf = bson_string_new (database->name); bson_string_append_c (buf, '.'); bson_string_append (buf, col_filter); BSON_APPEND_UTF8 (&legacy_filter, "name", buf->str); bson_string_free (buf, true); filter = &legacy_filter; } read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); cursor = mongoc_collection_find (col, MONGOC_QUERY_NONE, 0, 0, 0, filter ? filter : &q, NULL, read_prefs); _mongoc_cursor_transform_init ( cursor, _mongoc_database_find_collections_legacy_filter, _mongoc_database_find_collections_legacy_mutate, &bson_free, ctx); mongoc_read_prefs_destroy (read_prefs); cleanup_filter: mongoc_collection_destroy (col); return cursor; } mongoc_cursor_t * mongoc_database_find_collections (mongoc_database_t *database, const bson_t *filter, bson_error_t *error) { mongoc_cursor_t *cursor; mongoc_read_prefs_t *read_prefs; bson_t cmd = BSON_INITIALIZER; bson_t child; bson_error_t lerror; BSON_ASSERT (database); BSON_APPEND_INT32 (&cmd, "listCollections", 1); if (filter) { BSON_APPEND_DOCUMENT (&cmd, "filter", filter); BSON_APPEND_DOCUMENT_BEGIN (&cmd, "cursor", &child); bson_append_document_end (&cmd, &child); } read_prefs = mongoc_read_prefs_new (MONGOC_READ_PRIMARY); cursor = _mongoc_cursor_new (database->client, database->name, MONGOC_QUERY_SLAVE_OK, 0, 0, 0, true, NULL, NULL, NULL, NULL); _mongoc_cursor_cursorid_init (cursor, &cmd); if (_mongoc_cursor_cursorid_prime (cursor)) { /* intentionally empty */ } else { if (mongoc_cursor_error (cursor, &lerror)) { if (lerror.code == MONGOC_ERROR_QUERY_COMMAND_NOT_FOUND) { /* We are talking to a server that doesn' support listCollections. */ /* clear out the error. */ memset (&lerror, 0, sizeof lerror); /* try again with using system.namespaces */ mongoc_cursor_destroy (cursor); cursor = _mongoc_database_find_collections_legacy ( database, filter, error); } else if (error) { memcpy (error, &lerror, sizeof *error); } } } bson_destroy (&cmd); mongoc_read_prefs_destroy (read_prefs); return cursor; } char ** mongoc_database_get_collection_names (mongoc_database_t *database, bson_error_t *error) { bson_iter_t col; const char *name; char *namecopy; mongoc_array_t strv_buf; mongoc_cursor_t *cursor; const bson_t *doc; char **ret; BSON_ASSERT (database); cursor = mongoc_database_find_collections (database, NULL, error); if (!cursor) { return NULL; } _mongoc_array_init (&strv_buf, sizeof (char *)); while (mongoc_cursor_next (cursor, &doc)) { if (bson_iter_init (&col, doc) && bson_iter_find (&col, "name") && BSON_ITER_HOLDS_UTF8 (&col) && (name = bson_iter_utf8 (&col, NULL))) { namecopy = bson_strdup (name); _mongoc_array_append_val (&strv_buf, namecopy); } } /* append a null pointer for the last value. also handles the case * of no values. */ namecopy = NULL; _mongoc_array_append_val (&strv_buf, namecopy); if (mongoc_cursor_error (cursor, error)) { _mongoc_array_destroy (&strv_buf); ret = NULL; } else { ret = (char **)strv_buf.data; } mongoc_cursor_destroy (cursor); return ret; } mongoc_collection_t * mongoc_database_create_collection (mongoc_database_t *database, const char *name, const bson_t *options, bson_error_t *error) { mongoc_collection_t *collection = NULL; bson_iter_t iter; bson_t cmd; bool capped = false; BSON_ASSERT (database); BSON_ASSERT (name); if (strchr (name, '$')) { bson_set_error (error, MONGOC_ERROR_NAMESPACE, MONGOC_ERROR_NAMESPACE_INVALID, "The namespace \"%s\" is invalid.", name); return NULL; } if (options) { if (bson_iter_init_find (&iter, options, "capped")) { if (!BSON_ITER_HOLDS_BOOL (&iter)) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "The argument \"capped\" must be a boolean."); return NULL; } capped = bson_iter_bool (&iter); } if (bson_iter_init_find (&iter, options, "autoIndexId") && !BSON_ITER_HOLDS_BOOL (&iter)) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "The argument \"autoIndexId\" must be a boolean."); return NULL; } if (bson_iter_init_find (&iter, options, "size")) { if (!BSON_ITER_HOLDS_INT32 (&iter) && !BSON_ITER_HOLDS_INT64 (&iter)) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "The argument \"size\" must be an integer."); return NULL; } if (!capped) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "The \"size\" parameter requires {\"capped\": true}"); return NULL; } } if (bson_iter_init_find (&iter, options, "max")) { if (!BSON_ITER_HOLDS_INT32 (&iter) && !BSON_ITER_HOLDS_INT64 (&iter)) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "The argument \"max\" must be an integer."); return NULL; } if (!capped) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "The \"max\" parameter requires {\"capped\": true}"); return NULL; } } if (bson_iter_init_find (&iter, options, "storage")) { if (!BSON_ITER_HOLDS_DOCUMENT (&iter)) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "The \"storage\" parameter must be a document"); return NULL; } if (bson_iter_find (&iter, "wiredtiger")) { if (!BSON_ITER_HOLDS_DOCUMENT (&iter)) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "The \"wiredtiger\" option must take a document argument with a \"configString\" field"); return NULL; } if (bson_iter_find (&iter, "configString")) { if (!BSON_ITER_HOLDS_UTF8 (&iter)) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "The \"configString\" parameter must be a string"); return NULL; } } else { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "The \"wiredtiger\" option must take a document argument with a \"configString\" field"); return NULL; } } } } bson_init (&cmd); BSON_APPEND_UTF8 (&cmd, "create", name); if (options) { if (!bson_iter_init (&iter, options)) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "The argument \"options\" is corrupt or invalid."); bson_destroy (&cmd); return NULL; } while (bson_iter_next (&iter)) { if (!bson_append_iter (&cmd, bson_iter_key (&iter), -1, &iter)) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "Failed to append \"options\" to create command."); bson_destroy (&cmd); return NULL; } } } if (mongoc_database_command_simple (database, &cmd, NULL, NULL, error)) { collection = _mongoc_collection_new (database->client, database->name, name, database->read_prefs, database->read_concern, database->write_concern); } bson_destroy (&cmd); return collection; } mongoc_collection_t * mongoc_database_get_collection (mongoc_database_t *database, const char *collection) { BSON_ASSERT (database); BSON_ASSERT (collection); return _mongoc_collection_new (database->client, database->name, collection, database->read_prefs, database->read_concern, database->write_concern); } const char * mongoc_database_get_name (mongoc_database_t *database) { BSON_ASSERT (database); return database->name; } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-database.h0000664000175000017500000001500412673034026023014 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_DATABASE_H #define MONGOC_DATABASE_H #if !defined (MONGOC_INSIDE) && !defined (MONGOC_COMPILATION) # error "Only can be included directly." #endif #include #include "mongoc-cursor.h" #include "mongoc-flags.h" #include "mongoc-read-prefs.h" #include "mongoc-read-concern.h" #include "mongoc-write-concern.h" BSON_BEGIN_DECLS typedef struct _mongoc_database_t mongoc_database_t; const char *mongoc_database_get_name (mongoc_database_t *database); bool mongoc_database_remove_user (mongoc_database_t *database, const char *username, bson_error_t *error); bool mongoc_database_remove_all_users (mongoc_database_t *database, bson_error_t *error); bool mongoc_database_add_user (mongoc_database_t *database, const char *username, const char *password, const bson_t *roles, const bson_t *custom_data, bson_error_t *error); void mongoc_database_destroy (mongoc_database_t *database); mongoc_database_t *mongoc_database_copy (mongoc_database_t *database); mongoc_cursor_t *mongoc_database_command (mongoc_database_t *database, mongoc_query_flags_t flags, uint32_t skip, uint32_t limit, uint32_t batch_size, const bson_t *command, const bson_t *fields, const mongoc_read_prefs_t *read_prefs); bool mongoc_database_command_simple (mongoc_database_t *database, const bson_t *command, const mongoc_read_prefs_t *read_prefs, bson_t *reply, bson_error_t *error); bool mongoc_database_drop (mongoc_database_t *database, bson_error_t *error); bool mongoc_database_has_collection (mongoc_database_t *database, const char *name, bson_error_t *error); mongoc_collection_t *mongoc_database_create_collection (mongoc_database_t *database, const char *name, const bson_t *options, bson_error_t *error); const mongoc_read_prefs_t *mongoc_database_get_read_prefs (const mongoc_database_t *database); void mongoc_database_set_read_prefs (mongoc_database_t *database, const mongoc_read_prefs_t *read_prefs); const mongoc_write_concern_t *mongoc_database_get_write_concern (const mongoc_database_t *database); void mongoc_database_set_write_concern (mongoc_database_t *database, const mongoc_write_concern_t *write_concern); const mongoc_read_concern_t *mongoc_database_get_read_concern (const mongoc_database_t *database); void mongoc_database_set_read_concern (mongoc_database_t *database, const mongoc_read_concern_t *read_concern); mongoc_cursor_t *mongoc_database_find_collections (mongoc_database_t *database, const bson_t *filter, bson_error_t *error); char **mongoc_database_get_collection_names (mongoc_database_t *database, bson_error_t *error); mongoc_collection_t *mongoc_database_get_collection (mongoc_database_t *database, const char *name); BSON_END_DECLS #endif /* MONGOC_DATABASE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-errno-private.h0000664000175000017500000000267712673034026024061 0ustar jmikolajmikola/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_ERRNO_PRIVATE_H #define MONGOC_ERRNO_PRIVATE_H #if !defined (MONGOC_I_AM_A_DRIVER) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #include #include #ifdef _WIN32 # include # include #endif BSON_BEGIN_DECLS #if defined(_WIN32) # define MONGOC_ERRNO_IS_AGAIN(errno) ((errno == EAGAIN) || (errno == WSAEWOULDBLOCK) || (errno == WSAEINPROGRESS)) #elif defined(__sun) /* for some reason, accept() returns -1 and errno of 0 */ # define MONGOC_ERRNO_IS_AGAIN(errno) ((errno == EINTR) || (errno == EAGAIN) || (errno == EWOULDBLOCK) || (errno == EINPROGRESS) || (errno == 0)) #else # define MONGOC_ERRNO_IS_AGAIN(errno) ((errno == EINTR) || (errno == EAGAIN) || (errno == EWOULDBLOCK) || (errno == EINPROGRESS)) #endif BSON_END_DECLS #endif /* MONGOC_ERRNO_PRIVATE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-error.h0000664000175000017500000000541412673034026022405 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_ERRORS_H #define MONGOC_ERRORS_H #if !defined (MONGOC_INSIDE) && !defined (MONGOC_COMPILATION) # error "Only can be included directly." #endif #include BSON_BEGIN_DECLS typedef enum { MONGOC_ERROR_CLIENT = 1, MONGOC_ERROR_STREAM, MONGOC_ERROR_PROTOCOL, MONGOC_ERROR_CURSOR, MONGOC_ERROR_QUERY, MONGOC_ERROR_INSERT, MONGOC_ERROR_SASL, MONGOC_ERROR_BSON, MONGOC_ERROR_MATCHER, MONGOC_ERROR_NAMESPACE, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COLLECTION, MONGOC_ERROR_GRIDFS, MONGOC_ERROR_SCRAM, MONGOC_ERROR_SERVER_SELECTION, MONGOC_ERROR_WRITE_CONCERN, } mongoc_error_domain_t; typedef enum { MONGOC_ERROR_STREAM_INVALID_TYPE = 1, MONGOC_ERROR_STREAM_INVALID_STATE, MONGOC_ERROR_STREAM_NAME_RESOLUTION, MONGOC_ERROR_STREAM_SOCKET, MONGOC_ERROR_STREAM_CONNECT, MONGOC_ERROR_STREAM_NOT_ESTABLISHED, MONGOC_ERROR_CLIENT_NOT_READY, MONGOC_ERROR_CLIENT_TOO_BIG, MONGOC_ERROR_CLIENT_TOO_SMALL, MONGOC_ERROR_CLIENT_GETNONCE, MONGOC_ERROR_CLIENT_AUTHENTICATE, MONGOC_ERROR_CLIENT_NO_ACCEPTABLE_PEER, MONGOC_ERROR_CLIENT_IN_EXHAUST, MONGOC_ERROR_PROTOCOL_INVALID_REPLY, MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION, MONGOC_ERROR_CURSOR_INVALID_CURSOR, MONGOC_ERROR_QUERY_FAILURE, MONGOC_ERROR_BSON_INVALID, MONGOC_ERROR_MATCHER_INVALID, MONGOC_ERROR_NAMESPACE_INVALID, MONGOC_ERROR_NAMESPACE_INVALID_FILTER_TYPE, MONGOC_ERROR_COMMAND_INVALID_ARG, MONGOC_ERROR_COLLECTION_INSERT_FAILED, MONGOC_ERROR_COLLECTION_UPDATE_FAILED, MONGOC_ERROR_COLLECTION_DELETE_FAILED, MONGOC_ERROR_COLLECTION_DOES_NOT_EXIST = 26, MONGOC_ERROR_GRIDFS_INVALID_FILENAME, MONGOC_ERROR_SCRAM_NOT_DONE, MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, MONGOC_ERROR_QUERY_COMMAND_NOT_FOUND = 59, MONGOC_ERROR_QUERY_NOT_TAILABLE = 13051, MONGOC_ERROR_SERVER_SELECTION_BAD_WIRE_VERSION, MONGOC_ERROR_SERVER_SELECTION_FAILURE, MONGOC_ERROR_SERVER_SELECTION_INVALID_ID, MONGOC_ERROR_GRIDFS_CHUNK_MISSING, /* Dup with query failure. */ MONGOC_ERROR_PROTOCOL_ERROR = 17, MONGOC_ERROR_WRITE_CONCERN_ERROR = 64, } mongoc_error_code_t; BSON_END_DECLS #endif /* MONGOC_ERRORS_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-find-and-modify-private.h0000664000175000017500000000237312673034026025672 0ustar jmikolajmikola/* * Copyright 2015 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_FIND_AND_MODIFY_PRIVATE_H #define MONGOC_FIND_AND_MODIFY_PRIVATE_H #if !defined (MONGOC_INSIDE) && !defined (MONGOC_COMPILATION) # error "Only can be included directly." #endif #include #include "mongoc-write-command-private.h" BSON_BEGIN_DECLS struct _mongoc_find_and_modify_opts_t { bson_t *sort; bson_t *update; bson_t *fields; mongoc_find_and_modify_flags_t flags; mongoc_write_bypass_document_validation_t bypass_document_validation; }; BSON_END_DECLS #endif /* MONGOC_FIND_AND_MODIFY_PRIVATE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-find-and-modify.c0000664000175000017500000000644112673034026024215 0ustar jmikolajmikola/* * Copyright 2015 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "mongoc-write-concern.h" #include "mongoc-write-concern-private.h" #include "mongoc-find-and-modify.h" #include "mongoc-find-and-modify-private.h" #include "mongoc-util-private.h" /** * mongoc_find_and_modify_new: * * Create a new mongoc_find_and_modify_t. * * Returns: A newly allocated mongoc_find_and_modify_t. This should be freed * with mongoc_find_and_modify_destroy(). */ mongoc_find_and_modify_opts_t* mongoc_find_and_modify_opts_new (void) { mongoc_find_and_modify_opts_t *opts = NULL; opts = (mongoc_find_and_modify_opts_t *)bson_malloc0 (sizeof *opts); opts->bypass_document_validation = MONGOC_BYPASS_DOCUMENT_VALIDATION_DEFAULT; return opts; } bool mongoc_find_and_modify_opts_set_sort (mongoc_find_and_modify_opts_t *opts, const bson_t *sort) { BSON_ASSERT (opts); if (sort) { _mongoc_bson_destroy_if_set (opts->sort); opts->sort = bson_copy (sort); return true; } return false; } bool mongoc_find_and_modify_opts_set_update (mongoc_find_and_modify_opts_t *opts, const bson_t *update) { BSON_ASSERT (opts); if (update) { _mongoc_bson_destroy_if_set (opts->update); opts->update = bson_copy (update); return true; } return false; } bool mongoc_find_and_modify_opts_set_fields (mongoc_find_and_modify_opts_t *opts, const bson_t *fields) { BSON_ASSERT (opts); if (fields) { _mongoc_bson_destroy_if_set (opts->fields); opts->fields = bson_copy (fields); return true; } return false; } bool mongoc_find_and_modify_opts_set_flags (mongoc_find_and_modify_opts_t *opts, const mongoc_find_and_modify_flags_t flags) { BSON_ASSERT (opts); opts->flags = flags; return true; } bool mongoc_find_and_modify_opts_set_bypass_document_validation (mongoc_find_and_modify_opts_t *opts, bool bypass) { BSON_ASSERT (opts); opts->bypass_document_validation = bypass ? MONGOC_BYPASS_DOCUMENT_VALIDATION_TRUE : MONGOC_BYPASS_DOCUMENT_VALIDATION_FALSE; return true; } /** * mongoc_find_and_modify_opts_destroy: * @opts: A mongoc_find_and_modify_opts_t. * * Releases a mongoc_find_and_modify_opts_t and all associated memory. */ void mongoc_find_and_modify_opts_destroy (mongoc_find_and_modify_opts_t *opts) { if (opts) { _mongoc_bson_destroy_if_set (opts->sort); _mongoc_bson_destroy_if_set (opts->update); _mongoc_bson_destroy_if_set (opts->fields); bson_free (opts); } } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-find-and-modify.h0000664000175000017500000000441112673034026024215 0ustar jmikolajmikola/* * Copyright 2015 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_FIND_AND_MODIFY_H #define MONGOC_FIND_AND_MODIFY_H #if !defined (MONGOC_INSIDE) && !defined (MONGOC_COMPILATION) # error "Only can be included directly." #endif #include BSON_BEGIN_DECLS typedef enum { MONGOC_FIND_AND_MODIFY_NONE = 0, MONGOC_FIND_AND_MODIFY_REMOVE = 1 << 0, MONGOC_FIND_AND_MODIFY_UPSERT = 1 << 1, MONGOC_FIND_AND_MODIFY_RETURN_NEW = 1 << 2, } mongoc_find_and_modify_flags_t; typedef struct _mongoc_find_and_modify_opts_t mongoc_find_and_modify_opts_t ; mongoc_find_and_modify_opts_t* mongoc_find_and_modify_opts_new (void); bool mongoc_find_and_modify_opts_set_sort (mongoc_find_and_modify_opts_t *opts, const bson_t *sort); bool mongoc_find_and_modify_opts_set_update (mongoc_find_and_modify_opts_t *opts, const bson_t *update); bool mongoc_find_and_modify_opts_set_fields (mongoc_find_and_modify_opts_t *opts, const bson_t *fields); bool mongoc_find_and_modify_opts_set_flags (mongoc_find_and_modify_opts_t *opts, const mongoc_find_and_modify_flags_t flags); bool mongoc_find_and_modify_opts_set_bypass_document_validation (mongoc_find_and_modify_opts_t *opts, bool bypass); void mongoc_find_and_modify_opts_destroy (mongoc_find_and_modify_opts_t *opts); BSON_END_DECLS #endif /* MONGOC_FIND_AND_MODIFY_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-flags.h0000664000175000017500000001126412673034026022350 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_FLAGS_H #define MONGOC_FLAGS_H #if !defined (MONGOC_INSIDE) && !defined (MONGOC_COMPILATION) # error "Only can be included directly." #endif #include BSON_BEGIN_DECLS /** * mongoc_delete_flags_t: * @MONGOC_DELETE_NONE: Specify no delete flags. * @MONGOC_DELETE_SINGLE_REMOVE: Only remove the first document matching the * document selector. * * This type is only for use with deprecated functions and should not be * used in new code. Use mongoc_remove_flags_t instead. * * #mongoc_delete_flags_t are used when performing a delete operation. */ typedef enum { MONGOC_DELETE_NONE = 0, MONGOC_DELETE_SINGLE_REMOVE = 1 << 0, } mongoc_delete_flags_t; /** * mongoc_remove_flags_t: * @MONGOC_REMOVE_NONE: Specify no delete flags. * @MONGOC_REMOVE_SINGLE_REMOVE: Only remove the first document matching the * document selector. * * #mongoc_remove_flags_t are used when performing a remove operation. */ typedef enum { MONGOC_REMOVE_NONE = 0, MONGOC_REMOVE_SINGLE_REMOVE = 1 << 0, } mongoc_remove_flags_t; /** * mongoc_insert_flags_t: * @MONGOC_INSERT_NONE: Specify no insert flags. * @MONGOC_INSERT_CONTINUE_ON_ERROR: Continue inserting documents from * the insertion set even if one fails. * * #mongoc_insert_flags_t are used when performing an insert operation. */ typedef enum { MONGOC_INSERT_NONE = 0, MONGOC_INSERT_CONTINUE_ON_ERROR = 1 << 0, } mongoc_insert_flags_t; #define MONGOC_INSERT_NO_VALIDATE (1U << 31) /** * mongoc_query_flags_t: * @MONGOC_QUERY_NONE: No query flags supplied. * @MONGOC_QUERY_TAILABLE_CURSOR: Cursor will not be closed when the last * data is retrieved. You can resume this cursor later. * @MONGOC_QUERY_SLAVE_OK: Allow query of replica slave. * @MONGOC_QUERY_OPLOG_REPLAY: Used internally by Mongo. * @MONGOC_QUERY_NO_CURSOR_TIMEOUT: The server normally times out idle * cursors after an inactivity period (10 minutes). This prevents that. * @MONGOC_QUERY_AWAIT_DATA: Use with %MONGOC_QUERY_TAILABLE_CURSOR. Block * rather than returning no data. After a period, time out. * @MONGOC_QUERY_EXHAUST: Stream the data down full blast in multiple * "more" packages. Faster when you are pulling a lot of data and * know you want to pull it all down. * @MONGOC_QUERY_PARTIAL: Get partial results from mongos if some shards * are down (instead of throwing an error). * * #mongoc_query_flags_t is used for querying a Mongo instance. */ typedef enum { MONGOC_QUERY_NONE = 0, MONGOC_QUERY_TAILABLE_CURSOR = 1 << 1, MONGOC_QUERY_SLAVE_OK = 1 << 2, MONGOC_QUERY_OPLOG_REPLAY = 1 << 3, MONGOC_QUERY_NO_CURSOR_TIMEOUT = 1 << 4, MONGOC_QUERY_AWAIT_DATA = 1 << 5, MONGOC_QUERY_EXHAUST = 1 << 6, MONGOC_QUERY_PARTIAL = 1 << 7, } mongoc_query_flags_t; /** * mongoc_reply_flags_t: * @MONGOC_REPLY_NONE: No flags set. * @MONGOC_REPLY_CURSOR_NOT_FOUND: Cursor was not found. * @MONGOC_REPLY_QUERY_FAILURE: Query failed, error document provided. * @MONGOC_REPLY_SHARD_CONFIG_STALE: Shard configuration is stale. * @MONGOC_REPLY_AWAIT_CAPABLE: Wait for data to be returned until timeout * has passed. Used with %MONGOC_QUERY_TAILABLE_CURSOR. * * #mongoc_reply_flags_t contains flags supplied by the Mongo server in reply * to a request. */ typedef enum { MONGOC_REPLY_NONE = 0, MONGOC_REPLY_CURSOR_NOT_FOUND = 1 << 0, MONGOC_REPLY_QUERY_FAILURE = 1 << 1, MONGOC_REPLY_SHARD_CONFIG_STALE = 1 << 2, MONGOC_REPLY_AWAIT_CAPABLE = 1 << 3, } mongoc_reply_flags_t; /** * mongoc_update_flags_t: * @MONGOC_UPDATE_NONE: No update flags specified. * @MONGOC_UPDATE_UPSERT: Perform an upsert. * @MONGOC_UPDATE_MULTI_UPDATE: Continue updating after first match. * * #mongoc_update_flags_t is used when updating documents found in Mongo. */ typedef enum { MONGOC_UPDATE_NONE = 0, MONGOC_UPDATE_UPSERT = 1 << 0, MONGOC_UPDATE_MULTI_UPDATE = 1 << 1, } mongoc_update_flags_t; #define MONGOC_UPDATE_NO_VALIDATE (1U << 31) BSON_END_DECLS #endif /* MONGOC_FLAGS_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-gridfs-file-list-private.h0000664000175000017500000000253112673034026026065 0ustar jmikolajmikola/* * Copyright 2013 MongoDB Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_GRIDFS_FILE_LIST_PRIVATE_H #define MONGOC_GRIDFS_FILE_LIST_PRIVATE_H #if !defined (MONGOC_I_AM_A_DRIVER) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #include #include "mongoc-gridfs.h" #include "mongoc-gridfs-file.h" #include "mongoc-cursor.h" BSON_BEGIN_DECLS struct _mongoc_gridfs_file_list_t { mongoc_gridfs_t *gridfs; mongoc_cursor_t *cursor; bson_error_t error; }; mongoc_gridfs_file_list_t *_mongoc_gridfs_file_list_new (mongoc_gridfs_t *gridfs, const bson_t *query, uint32_t limit); BSON_END_DECLS #endif /* MONGOC_GRIDFS_FILE_LIST_PRIVATE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-gridfs-file-list.c0000664000175000017500000000423512673034026024413 0ustar jmikolajmikola/* * Copyright 2013 MongoDB Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include "mongoc-cursor.h" #include "mongoc-cursor-private.h" #include "mongoc-gridfs.h" #include "mongoc-gridfs-private.h" #include "mongoc-gridfs-file.h" #include "mongoc-gridfs-file-private.h" #include "mongoc-gridfs-file-list.h" #include "mongoc-gridfs-file-list-private.h" #include "mongoc-trace.h" #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "gridfs_file_list" mongoc_gridfs_file_list_t * _mongoc_gridfs_file_list_new (mongoc_gridfs_t *gridfs, const bson_t *query, uint32_t limit) { mongoc_gridfs_file_list_t *list; mongoc_cursor_t *cursor; cursor = mongoc_collection_find (gridfs->files, MONGOC_QUERY_NONE, 0, limit, 0, query, NULL, NULL); BSON_ASSERT (cursor); list = (mongoc_gridfs_file_list_t *)bson_malloc0 (sizeof *list); list->cursor = cursor; list->gridfs = gridfs; return list; } mongoc_gridfs_file_t * mongoc_gridfs_file_list_next (mongoc_gridfs_file_list_t *list) { const bson_t *bson; BSON_ASSERT (list); if (mongoc_cursor_next (list->cursor, &bson)) { return _mongoc_gridfs_file_new_from_bson (list->gridfs, bson); } else { return NULL; } } bool mongoc_gridfs_file_list_error (mongoc_gridfs_file_list_t *list, bson_error_t *error) { return mongoc_cursor_error(list->cursor, error); } void mongoc_gridfs_file_list_destroy (mongoc_gridfs_file_list_t *list) { BSON_ASSERT (list); mongoc_cursor_destroy (list->cursor); bson_free (list); } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-gridfs-file-list.h0000664000175000017500000000247712673034026024426 0ustar jmikolajmikola/* * Copyright 2013 MongoDB Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_GRIDFS_FILE_LIST_H #define MONGOC_GRIDFS_FILE_LIST_H #if !defined (MONGOC_INSIDE) && !defined (MONGOC_COMPILATION) # error "Only can be included directly." #endif #include #include "mongoc-gridfs-file.h" BSON_BEGIN_DECLS typedef struct _mongoc_gridfs_file_list_t mongoc_gridfs_file_list_t; mongoc_gridfs_file_t *mongoc_gridfs_file_list_next (mongoc_gridfs_file_list_t *list); void mongoc_gridfs_file_list_destroy (mongoc_gridfs_file_list_t *list); bool mongoc_gridfs_file_list_error (mongoc_gridfs_file_list_t *list, bson_error_t *error); BSON_END_DECLS #endif /* MONGOC_GRIDFS_FILE_LIST_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-gridfs-file-page-private.h0000664000175000017500000000542712673034026026035 0ustar jmikolajmikola/* * Copyright 2013 MongoDB Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_GRIDFS_FILE_PAGE_PRIVATE_H #define MONGOC_GRIDFS_FILE_PAGE_PRIVATE_H #if !defined (MONGOC_I_AM_A_DRIVER) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #include #include "mongoc-gridfs-file.h" BSON_BEGIN_DECLS struct _mongoc_gridfs_file_page_t { const uint8_t *read_buf; uint8_t *buf; uint32_t len; uint32_t chunk_size; uint32_t offset; }; mongoc_gridfs_file_page_t *_mongoc_gridfs_file_page_new (const uint8_t *data, uint32_t len, uint32_t chunk_size); void _mongoc_gridfs_file_page_destroy (mongoc_gridfs_file_page_t *page); bool _mongoc_gridfs_file_page_seek (mongoc_gridfs_file_page_t *page, uint32_t offset); int32_t _mongoc_gridfs_file_page_read (mongoc_gridfs_file_page_t *page, void *dst, uint32_t len); int32_t _mongoc_gridfs_file_page_write (mongoc_gridfs_file_page_t *page, const void *src, uint32_t len); bool _mongoc_gridfs_file_page_memset0 (mongoc_gridfs_file_page_t *page, uint32_t len); uint32_t _mongoc_gridfs_file_page_tell (mongoc_gridfs_file_page_t *page); const uint8_t *_mongoc_gridfs_file_page_get_data (mongoc_gridfs_file_page_t *page); uint32_t _mongoc_gridfs_file_page_get_len (mongoc_gridfs_file_page_t *page); bool _mongoc_gridfs_file_page_is_dirty (mongoc_gridfs_file_page_t *page); BSON_END_DECLS #endif /* MONGOC_GRIDFS_FILE_PAGE_PRIVATE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-gridfs-file-page.c0000664000175000017500000001213212673034026024347 0ustar jmikolajmikola/* * Copyright 2013 MongoDB Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "gridfs_file_page" #include "mongoc-gridfs-file-page.h" #include "mongoc-gridfs-file-page-private.h" #include "mongoc-trace.h" /** create a new page from a buffer * * The buffer should stick around for the life of the page */ mongoc_gridfs_file_page_t * _mongoc_gridfs_file_page_new (const uint8_t *data, uint32_t len, uint32_t chunk_size) { mongoc_gridfs_file_page_t *page; ENTRY; BSON_ASSERT (data); BSON_ASSERT (len <= chunk_size); page = (mongoc_gridfs_file_page_t *)bson_malloc0 (sizeof *page); page->chunk_size = chunk_size; page->read_buf = data; page->len = len; RETURN (page); } bool _mongoc_gridfs_file_page_seek (mongoc_gridfs_file_page_t *page, uint32_t offset) { ENTRY; BSON_ASSERT (page); page->offset = offset; RETURN (1); } int32_t _mongoc_gridfs_file_page_read (mongoc_gridfs_file_page_t *page, void *dst, uint32_t len) { int bytes_read; const uint8_t *src; ENTRY; BSON_ASSERT (page); BSON_ASSERT (dst); bytes_read = BSON_MIN (len, page->len - page->offset); src = page->read_buf ? page->read_buf : page->buf; memcpy (dst, src + page->offset, bytes_read); page->offset += bytes_read; RETURN (bytes_read); } /** * _mongoc_gridfs_file_page_write: * * Write to a page. * * Writes are copy-on-write with regards to the buffer that was passed to the * mongoc_gridfs_file_page_t during construction. In other words, the first * write allocates a large enough buffer for file->chunk_size, which becomes * authoritative from then on. * * A write of zero bytes will trigger the copy-on-write mechanism. */ int32_t _mongoc_gridfs_file_page_write (mongoc_gridfs_file_page_t *page, const void *src, uint32_t len) { int bytes_written; ENTRY; BSON_ASSERT (page); BSON_ASSERT (src); bytes_written = BSON_MIN (len, page->chunk_size - page->offset); if (!page->buf) { page->buf = (uint8_t *) bson_malloc (page->chunk_size); memcpy (page->buf, page->read_buf, BSON_MIN (page->chunk_size, page->len)); } /* Copy bytes and adjust the page position */ memcpy (page->buf + page->offset, src, bytes_written); page->offset += bytes_written; page->len = BSON_MAX (page->offset, page->len); /* Don't use the old read buffer, which is no longer current */ page->read_buf = page->buf; RETURN (bytes_written); } /** * _mongoc_gridfs_file_page_memset0: * * Write zeros to a page, starting from the page's current position. Up to * `len` bytes will be set to zero or until the page is full, whichever * comes first. * * Like _mongoc_gridfs_file_page_write, operations are copy-on-write with * regards to the page buffer. * * Returns: * True on success; false otherwise. */ bool _mongoc_gridfs_file_page_memset0 (mongoc_gridfs_file_page_t *page, uint32_t len) { int32_t bytes_set; ENTRY; BSON_ASSERT (page); bytes_set = BSON_MIN (page->chunk_size - page->offset, len); if (!page->buf) { page->buf = (uint8_t *)bson_malloc0 (page->chunk_size); memcpy (page->buf, page->read_buf, BSON_MIN (page->chunk_size, page->len)); } /* Set bytes and adjust the page position */ memset (page->buf + page->offset, '\0', bytes_set); page->offset += bytes_set; page->len = BSON_MAX (page->offset, page->len); /* Don't use the old read buffer, which is no longer current */ page->read_buf = page->buf; RETURN (true); } const uint8_t * _mongoc_gridfs_file_page_get_data (mongoc_gridfs_file_page_t *page) { ENTRY; BSON_ASSERT (page); RETURN (page->buf ? page->buf : page->read_buf); } uint32_t _mongoc_gridfs_file_page_get_len (mongoc_gridfs_file_page_t *page) { ENTRY; BSON_ASSERT (page); RETURN (page->len); } uint32_t _mongoc_gridfs_file_page_tell (mongoc_gridfs_file_page_t *page) { ENTRY; BSON_ASSERT (page); RETURN (page->offset); } bool _mongoc_gridfs_file_page_is_dirty (mongoc_gridfs_file_page_t *page) { ENTRY; BSON_ASSERT (page); RETURN (page->buf ? 1 : 0); } void _mongoc_gridfs_file_page_destroy (mongoc_gridfs_file_page_t *page) { ENTRY; if (page->buf) { bson_free (page->buf); } bson_free (page); EXIT; } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-gridfs-file-page.h0000664000175000017500000000203112673034026024351 0ustar jmikolajmikola/* * Copyright 2013 MongoDB Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_GRIDFS_FILE_PAGE_H #define MONGOC_GRIDFS_FILE_PAGE_H #if !defined (MONGOC_INSIDE) && !defined (MONGOC_COMPILATION) # error "Only can be included directly." #endif #include #include "mongoc-stream.h" #include "mongoc-gridfs-file.h" #include "mongoc-gridfs-file-list.h" BSON_BEGIN_DECLS typedef struct _mongoc_gridfs_file_page_t mongoc_gridfs_file_page_t; BSON_END_DECLS #endif /* MONGOC_GRIDFS_FILE_PAGE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-gridfs-file-private.h0000664000175000017500000000451212673034026025115 0ustar jmikolajmikola/* * Copyright 2013 MongoDB Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_GRIDFS_FILE_PRIVATE_H #define MONGOC_GRIDFS_FILE_PRIVATE_H #if !defined (MONGOC_I_AM_A_DRIVER) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #include #include "mongoc-gridfs.h" #include "mongoc-gridfs-file.h" #include "mongoc-gridfs-file-page.h" #include "mongoc-cursor.h" BSON_BEGIN_DECLS struct _mongoc_gridfs_file_t { mongoc_gridfs_t *gridfs; bson_t bson; mongoc_gridfs_file_page_t *page; uint64_t pos; int32_t n; bson_error_t error; mongoc_cursor_t *cursor; uint32_t cursor_range[2]; /* current chunk, # of chunks */ bool is_dirty; bson_value_t files_id; int64_t length; int32_t chunk_size; int64_t upload_date; char *md5; char *filename; char *content_type; bson_t aliases; bson_t metadata; const char *bson_md5; const char *bson_filename; const char *bson_content_type; bson_t bson_aliases; bson_t bson_metadata; }; mongoc_gridfs_file_t *_mongoc_gridfs_file_new_from_bson (mongoc_gridfs_t *gridfs, const bson_t *data); mongoc_gridfs_file_t *_mongoc_gridfs_file_new (mongoc_gridfs_t *gridfs, mongoc_gridfs_file_opt_t *opt); BSON_END_DECLS #endif /* MONGOC_GRIDFS_FILE_PRIVATE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-gridfs-file.c0000664000175000017500000006404412673034026023446 0ustar jmikolajmikola/* * Copyright 2013 MongoDB Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "gridfs_file" #include #include #include #include "mongoc-cursor.h" #include "mongoc-cursor-private.h" #include "mongoc-collection.h" #include "mongoc-gridfs.h" #include "mongoc-gridfs-private.h" #include "mongoc-gridfs-file.h" #include "mongoc-gridfs-file-private.h" #include "mongoc-gridfs-file-page.h" #include "mongoc-gridfs-file-page-private.h" #include "mongoc-iovec.h" #include "mongoc-trace.h" #include "mongoc-error.h" static bool _mongoc_gridfs_file_refresh_page (mongoc_gridfs_file_t *file); static bool _mongoc_gridfs_file_flush_page (mongoc_gridfs_file_t *file); static ssize_t _mongoc_gridfs_file_extend (mongoc_gridfs_file_t *file); /***************************************************************** * Magic accessor generation * * We need some accessors to get and set properties on files, to handle memory * ownership and to determine dirtiness. These macros produce the getters and * setters we need *****************************************************************/ #define MONGOC_GRIDFS_FILE_STR_ACCESSOR(name) \ const char * \ mongoc_gridfs_file_get_##name (mongoc_gridfs_file_t * file) \ { \ return file->name ? file->name : file->bson_##name; \ } \ void \ mongoc_gridfs_file_set_##name (mongoc_gridfs_file_t * file, \ const char *str) \ { \ if (file->name) { \ bson_free (file->name); \ } \ file->name = bson_strdup (str); \ file->is_dirty = 1; \ } #define MONGOC_GRIDFS_FILE_BSON_ACCESSOR(name) \ const bson_t * \ mongoc_gridfs_file_get_##name (mongoc_gridfs_file_t * file) \ { \ if (file->name.len) { \ return &file->name; \ } else if (file->bson_##name.len) { \ return &file->bson_##name; \ } else { \ return NULL; \ } \ } \ void \ mongoc_gridfs_file_set_##name (mongoc_gridfs_file_t * file, \ const bson_t * bson) \ { \ if (file->name.len) { \ bson_destroy (&file->name); \ } \ bson_copy_to (bson, &(file->name)); \ file->is_dirty = 1; \ } MONGOC_GRIDFS_FILE_STR_ACCESSOR (md5) MONGOC_GRIDFS_FILE_STR_ACCESSOR (filename) MONGOC_GRIDFS_FILE_STR_ACCESSOR (content_type) MONGOC_GRIDFS_FILE_BSON_ACCESSOR (aliases) MONGOC_GRIDFS_FILE_BSON_ACCESSOR (metadata) /** save a gridfs file */ bool mongoc_gridfs_file_save (mongoc_gridfs_file_t *file) { bson_t *selector, *update, child; const char *md5; const char *filename; const char *content_type; const bson_t *aliases; const bson_t *metadata; bool r; ENTRY; if (!file->is_dirty) { return 1; } if (file->page && _mongoc_gridfs_file_page_is_dirty (file->page)) { _mongoc_gridfs_file_flush_page (file); } md5 = mongoc_gridfs_file_get_md5 (file); filename = mongoc_gridfs_file_get_filename (file); content_type = mongoc_gridfs_file_get_content_type (file); aliases = mongoc_gridfs_file_get_aliases (file); metadata = mongoc_gridfs_file_get_metadata (file); selector = bson_new (); bson_append_value (selector, "_id", -1, &file->files_id); update = bson_new (); bson_append_document_begin (update, "$set", -1, &child); bson_append_int64 (&child, "length", -1, file->length); bson_append_int32 (&child, "chunkSize", -1, file->chunk_size); bson_append_date_time (&child, "uploadDate", -1, file->upload_date); if (md5) { bson_append_utf8 (&child, "md5", -1, md5, -1); } if (filename) { bson_append_utf8 (&child, "filename", -1, filename, -1); } if (content_type) { bson_append_utf8 (&child, "contentType", -1, content_type, -1); } if (aliases) { bson_append_array (&child, "aliases", -1, aliases); } if (metadata) { bson_append_document (&child, "metadata", -1, metadata); } bson_append_document_end (update, &child); r = mongoc_collection_update (file->gridfs->files, MONGOC_UPDATE_UPSERT, selector, update, NULL, &file->error); bson_destroy (selector); bson_destroy (update); file->is_dirty = 0; RETURN (r); } /** * _mongoc_gridfs_file_new_from_bson: * * creates a gridfs file from a bson object * * This is only really useful for instantiating a gridfs file from a server * side object */ mongoc_gridfs_file_t * _mongoc_gridfs_file_new_from_bson (mongoc_gridfs_t *gridfs, const bson_t *data) { mongoc_gridfs_file_t *file; const bson_value_t *value; const char *key; bson_iter_t iter; const uint8_t *buf; uint32_t buf_len; ENTRY; BSON_ASSERT (gridfs); BSON_ASSERT (data); file = (mongoc_gridfs_file_t *)bson_malloc0 (sizeof *file); file->gridfs = gridfs; bson_copy_to (data, &file->bson); bson_iter_init (&iter, &file->bson); while (bson_iter_next (&iter)) { key = bson_iter_key (&iter); if (0 == strcmp (key, "_id")) { value = bson_iter_value (&iter); bson_value_copy (value, &file->files_id); } else if (0 == strcmp (key, "length")) { if (!BSON_ITER_HOLDS_INT32 (&iter) && !BSON_ITER_HOLDS_INT64 (&iter) && !BSON_ITER_HOLDS_DOUBLE (&iter)) { GOTO (failure); } file->length = bson_iter_as_int64 (&iter); } else if (0 == strcmp (key, "chunkSize")) { if (!BSON_ITER_HOLDS_INT32 (&iter) && !BSON_ITER_HOLDS_INT64 (&iter) && !BSON_ITER_HOLDS_DOUBLE (&iter)) { GOTO (failure); } if (bson_iter_as_int64 (&iter) > INT32_MAX) { GOTO (failure); } file->chunk_size = (int32_t)bson_iter_as_int64 (&iter); } else if (0 == strcmp (key, "uploadDate")) { if (!BSON_ITER_HOLDS_DATE_TIME (&iter)){ GOTO (failure); } file->upload_date = bson_iter_date_time (&iter); } else if (0 == strcmp (key, "md5")) { if (!BSON_ITER_HOLDS_UTF8 (&iter)) { GOTO (failure); } file->bson_md5 = bson_iter_utf8 (&iter, NULL); } else if (0 == strcmp (key, "filename")) { if (!BSON_ITER_HOLDS_UTF8 (&iter)) { GOTO (failure); } file->bson_filename = bson_iter_utf8 (&iter, NULL); } else if (0 == strcmp (key, "contentType")) { if (!BSON_ITER_HOLDS_UTF8 (&iter)) { GOTO (failure); } file->bson_content_type = bson_iter_utf8 (&iter, NULL); } else if (0 == strcmp (key, "aliases")) { if (!BSON_ITER_HOLDS_ARRAY (&iter)) { GOTO (failure); } bson_iter_array (&iter, &buf_len, &buf); bson_init_static (&file->bson_aliases, buf, buf_len); } else if (0 == strcmp (key, "metadata")) { if (!BSON_ITER_HOLDS_DOCUMENT (&iter)) { GOTO (failure); } bson_iter_document (&iter, &buf_len, &buf); bson_init_static (&file->bson_metadata, buf, buf_len); } } /* TODO: is there are a minimal object we should be verifying that we * actually have here? */ RETURN (file); failure: bson_destroy (&file->bson); RETURN (NULL); } /** * _mongoc_gridfs_file_new: * * Create a new empty gridfs file */ mongoc_gridfs_file_t * _mongoc_gridfs_file_new (mongoc_gridfs_t *gridfs, mongoc_gridfs_file_opt_t *opt) { mongoc_gridfs_file_t *file; mongoc_gridfs_file_opt_t default_opt = { 0 }; ENTRY; BSON_ASSERT (gridfs); if (!opt) { opt = &default_opt; } file = (mongoc_gridfs_file_t *)bson_malloc0 (sizeof *file); file->gridfs = gridfs; file->is_dirty = 1; if (opt->chunk_size) { file->chunk_size = opt->chunk_size; } else { /* * The default chunk size is now 255kb. This used to be 256k but has been * reduced to allow for them to fit within power of two sizes in mongod. * * See CDRIVER-322. */ file->chunk_size = (1 << 18) - 1024; } file->files_id.value_type = BSON_TYPE_OID; bson_oid_init (&file->files_id.value.v_oid, NULL); file->upload_date = time (NULL) * 1000; if (opt->md5) { file->md5 = bson_strdup (opt->md5); } if (opt->filename) { file->filename = bson_strdup (opt->filename); } if (opt->content_type) { file->content_type = bson_strdup (opt->content_type); } if (opt->aliases) { bson_copy_to (opt->aliases, &(file->aliases)); } if (opt->metadata) { bson_copy_to (opt->metadata, &(file->metadata)); } file->pos = 0; file->n = 0; RETURN (file); } void mongoc_gridfs_file_destroy (mongoc_gridfs_file_t *file) { ENTRY; BSON_ASSERT (file); if (file->page) { _mongoc_gridfs_file_page_destroy (file->page); } if (file->bson.len) { bson_destroy (&file->bson); } if (file->cursor) { mongoc_cursor_destroy (file->cursor); } if (file->files_id.value_type) { bson_value_destroy (&file->files_id); } if (file->md5) { bson_free (file->md5); } if (file->filename) { bson_free (file->filename); } if (file->content_type) { bson_free (file->content_type); } if (file->aliases.len) { bson_destroy (&file->aliases); } if (file->bson_aliases.len) { bson_destroy (&file->bson_aliases); } if (file->metadata.len) { bson_destroy (&file->metadata); } if (file->bson_metadata.len) { bson_destroy (&file->bson_metadata); } bson_free (file); EXIT; } /** readv against a gridfs file */ ssize_t mongoc_gridfs_file_readv (mongoc_gridfs_file_t *file, mongoc_iovec_t *iov, size_t iovcnt, size_t min_bytes, uint32_t timeout_msec) { uint32_t bytes_read = 0; int32_t r; size_t i; uint32_t iov_pos; ENTRY; BSON_ASSERT (file); BSON_ASSERT (iov); BSON_ASSERT (iovcnt); BSON_ASSERT (timeout_msec <= INT_MAX); /* TODO: we should probably do something about timeout_msec here */ /* Reading when positioned past the end does nothing */ if (file->pos >= file->length) { return 0; } /* Try to get the current chunk */ if (!file->page && !_mongoc_gridfs_file_refresh_page (file)) { return -1; } for (i = 0; i < iovcnt; i++) { iov_pos = 0; for (;; ) { r = _mongoc_gridfs_file_page_read (file->page, (uint8_t *)iov[i].iov_base + iov_pos, (uint32_t)(iov[i].iov_len - iov_pos)); BSON_ASSERT (r >= 0); iov_pos += r; file->pos += r; bytes_read += r; if (iov_pos == iov[i].iov_len) { /* filled a bucket, keep going */ break; } else if (file->length == file->pos) { /* we're at the end of the file. So we're done */ RETURN (bytes_read); } else if (bytes_read >= min_bytes) { /* we need a new page, but we've read enough bytes to stop */ RETURN (bytes_read); } else if (!_mongoc_gridfs_file_refresh_page (file)) { /* more to read, just on a new page */ return -1; } } } RETURN (bytes_read); } /** writev against a gridfs file */ ssize_t mongoc_gridfs_file_writev (mongoc_gridfs_file_t *file, mongoc_iovec_t *iov, size_t iovcnt, uint32_t timeout_msec) { uint32_t bytes_written = 0; int32_t r; size_t i; uint32_t iov_pos; ENTRY; BSON_ASSERT (file); BSON_ASSERT (iov); BSON_ASSERT (iovcnt); BSON_ASSERT (timeout_msec <= INT_MAX); /* TODO: we should probably do something about timeout_msec here */ /* Pull in the correct page */ if (!file->page && !_mongoc_gridfs_file_refresh_page (file)) { return -1; } /* When writing past the end-of-file, fill the gap with zeros */ if (file->pos > file->length && !_mongoc_gridfs_file_extend (file)) { return -1; } for (i = 0; i < iovcnt; i++) { iov_pos = 0; for (;; ) { if (!file->page && !_mongoc_gridfs_file_refresh_page (file)) { return -1; } /* write bytes until an iov is exhausted or the page is full */ r = _mongoc_gridfs_file_page_write (file->page, (uint8_t *)iov[i].iov_base + iov_pos, (uint32_t)(iov[i].iov_len - iov_pos)); BSON_ASSERT (r >= 0); iov_pos += r; file->pos += r; bytes_written += r; file->length = BSON_MAX (file->length, (int64_t)file->pos); if (iov_pos == iov[i].iov_len) { /** filled a bucket, keep going */ break; } else { /** flush the buffer, the next pass through will bring in a new page */ _mongoc_gridfs_file_flush_page (file); } } } file->is_dirty = 1; RETURN (bytes_written); } /** * _mongoc_gridfs_file_extend: * * Extend a GridFS file to the current position pointer. Zeros will be * appended to the end of the file until file->length is even with file->pos. * * If file->length >= file->pos, the function exits successfully with no * operation performed. * * Parameters: * @file: A mongoc_gridfs_file_t. * * Returns: * The number of zero bytes written, or -1 on failure. */ static ssize_t _mongoc_gridfs_file_extend (mongoc_gridfs_file_t *file) { int64_t target_length; ssize_t diff; ENTRY; BSON_ASSERT (file); if (file->length >= file->pos) { RETURN (0); } diff = (ssize_t)(file->pos - file->length); target_length = file->pos; mongoc_gridfs_file_seek (file, 0, SEEK_END); while (true) { if (!file->page && !_mongoc_gridfs_file_refresh_page (file)) { RETURN (-1); } /* Set bytes until we reach the limit or fill a page */ file->pos += _mongoc_gridfs_file_page_memset0 (file->page, target_length - file->pos); if (file->pos == target_length) { /* We're done */ break; } else if (!_mongoc_gridfs_file_flush_page (file)) { /* We tried to flush a full buffer, but an error occurred */ RETURN (-1); } } BSON_ASSERT (file->length = target_length); file->is_dirty = true; RETURN (diff); } /** * _mongoc_gridfs_file_flush_page: * * Unconditionally flushes the file's current page to the database. * The page to flush is determined by page->n. * * Side Effects: * * On success, file->page is properly destroyed and set to NULL. * * Returns: * * True on success; false otherwise. */ static bool _mongoc_gridfs_file_flush_page (mongoc_gridfs_file_t *file) { bson_t *selector, *update; bool r; const uint8_t *buf; uint32_t len; ENTRY; BSON_ASSERT (file); BSON_ASSERT (file->page); buf = _mongoc_gridfs_file_page_get_data (file->page); len = _mongoc_gridfs_file_page_get_len (file->page); selector = bson_new (); bson_append_value (selector, "files_id", -1, &file->files_id); bson_append_int32 (selector, "n", -1, file->n); update = bson_sized_new (file->chunk_size + 100); bson_append_value (update, "files_id", -1, &file->files_id); bson_append_int32 (update, "n", -1, file->n); bson_append_binary (update, "data", -1, BSON_SUBTYPE_BINARY, buf, len); r = mongoc_collection_update (file->gridfs->chunks, MONGOC_UPDATE_UPSERT, selector, update, NULL, &file->error); bson_destroy (selector); bson_destroy (update); if (r) { _mongoc_gridfs_file_page_destroy (file->page); file->page = NULL; r = mongoc_gridfs_file_save (file); } RETURN (r); } /** * _mongoc_gridfs_file_keep_cursor: * * After a seek, decide if the next read should use the current cursor or * start a new query. * * Preconditions: * * file has a cursor and cursor range. * * Side Effects: * * None. */ static bool _mongoc_gridfs_file_keep_cursor (mongoc_gridfs_file_t *file) { uint32_t chunk_no; uint32_t chunks_per_batch; if (file->n < 0 || file->chunk_size <= 0) { return false; } chunk_no = (uint32_t) file->n; /* server returns roughly 4 MB batches by default */ chunks_per_batch = (4 * 1024 * 1024) / (uint32_t) file->chunk_size; return ( /* cursor is on or before the desired chunk */ file->cursor_range[0] <= chunk_no && /* chunk_no is before end of file */ chunk_no <= file->cursor_range[1] && /* desired chunk is in this batch or next one */ chunk_no < file->cursor_range[0] + 2 * chunks_per_batch); } /** * _mongoc_gridfs_file_refresh_page: * * Refresh a GridFS file's underlying page. This recalculates the current * page number based on the file's stream position, then fetches that page * from the database. * * Note that this fetch is unconditional and the page is queried from the * database even if the current page covers the same theoretical chunk. * * * Side Effects: * * file->page is loaded with the appropriate buffer, fetched from the * database. If the file position is at the end of the file and on a new * chunk boundary, a new page is created. We currently DO NOT handle the case * of the file position being far past the end-of-file. * * file->n is set based on file->pos. file->error is set on error. */ static bool _mongoc_gridfs_file_refresh_page (mongoc_gridfs_file_t *file) { bson_t *query, *fields, child, child2; const bson_t *chunk; const char *key; bson_iter_t iter; const uint8_t *data; uint32_t len; ENTRY; BSON_ASSERT (file); file->n = (int32_t)(file->pos / file->chunk_size); if (file->page) { _mongoc_gridfs_file_page_destroy (file->page); file->page = NULL; } /* if the file pointer is past the end of the current file (I.e. pointing to * a new chunk) and we're on a chunk boundary, we'll pass the page * constructor a new empty page */ if ((int64_t)file->pos >= file->length && !(file->pos % file->chunk_size)) { data = (uint8_t *)""; len = 0; } else { /* if we have a cursor, but the cursor doesn't have the chunk we're going * to need, destroy it (we'll grab a new one immediately there after) */ if (file->cursor && !_mongoc_gridfs_file_keep_cursor (file)) { mongoc_cursor_destroy (file->cursor); file->cursor = NULL; } if (!file->cursor) { query = bson_new (); bson_append_document_begin(query, "$query", -1, &child); bson_append_value (&child, "files_id", -1, &file->files_id); bson_append_document_begin (&child, "n", -1, &child2); bson_append_int32 (&child2, "$gte", -1, file->n); bson_append_document_end (&child, &child2); bson_append_document_end(query, &child); bson_append_document_begin(query, "$orderby", -1, &child); bson_append_int32 (&child, "n", -1, 1); bson_append_document_end(query, &child); fields = bson_new (); bson_append_int32 (fields, "n", -1, 1); bson_append_int32 (fields, "data", -1, 1); bson_append_int32 (fields, "_id", -1, 0); /* find all chunks greater than or equal to our current file pos */ file->cursor = mongoc_collection_find (file->gridfs->chunks, MONGOC_QUERY_NONE, 0, 0, 0, query, fields, NULL); file->cursor_range[0] = file->n; file->cursor_range[1] = (uint32_t)(file->length / file->chunk_size); bson_destroy (query); bson_destroy (fields); BSON_ASSERT (file->cursor); } /* we might have had a cursor before, then seeked ahead past a chunk. * iterate until we're on the right chunk */ while (file->cursor_range[0] <= file->n) { if (!mongoc_cursor_next (file->cursor, &chunk)) { /* copy cursor error, if any. might just lack a matching chunk. */ mongoc_cursor_error (file->cursor, &file->error); RETURN (0); } file->cursor_range[0]++; } bson_iter_init (&iter, chunk); /* grab out what we need from the chunk */ while (bson_iter_next (&iter)) { key = bson_iter_key (&iter); if (strcmp (key, "n") == 0) { if (file->n != bson_iter_int32 (&iter)) { bson_set_error (&file->error, MONGOC_ERROR_GRIDFS, MONGOC_ERROR_GRIDFS_CHUNK_MISSING, "missing chunk number %" PRId32, file->n); RETURN (0); } } else if (strcmp (key, "data") == 0) { bson_iter_binary (&iter, NULL, &len, &data); } else { /* Unexpected key. This should never happen */ RETURN (0); } } if (file->n != file->pos / file->chunk_size) { return 0; } } file->page = _mongoc_gridfs_file_page_new (data, len, file->chunk_size); /* seek in the page towards wherever we're supposed to be */ RETURN (_mongoc_gridfs_file_page_seek (file->page, file->pos % file->chunk_size)); } /** * mongoc_gridfs_file_seek: * * Adjust the file position pointer in `file` by `delta`, starting from the * position `whence`. The `whence` argument is interpreted as in fseek(2): * * SEEK_SET Set the position relative to the start of the file. * SEEK_CUR Move `delta` from the current file position. * SEEK_END Move `delta` from the end-of-file. * * Parameters: * * @file: A mongoc_gridfs_file_t. * @delta: The amount to move. May be positive or negative. * @whence: One of SEEK_SET, SEEK_CUR or SEEK_END. * * Errors: * * [EINVAL] `whence` is not one of SEEK_SET, SEEK_CUR or SEEK_END. * [EINVAL] Resulting file position would be negative. * * Side Effects: * * On success, the file's underlying position pointer is set appropriately. * On failure, the file position is NOT changed and errno is set. * * Returns: * * 0 on success. * -1 on error, and errno set to indicate the error. */ int mongoc_gridfs_file_seek (mongoc_gridfs_file_t *file, int64_t delta, int whence) { int64_t offset; BSON_ASSERT (file); switch (whence) { case SEEK_SET: offset = delta; break; case SEEK_CUR: offset = file->pos + delta; break; case SEEK_END: offset = file->length + delta; break; default: errno = EINVAL; return -1; break; } if (offset < 0) { errno = EINVAL; return -1; } if (offset / file->chunk_size != file->n) { /** no longer on the same page */ if (file->page) { if (_mongoc_gridfs_file_page_is_dirty (file->page)) { _mongoc_gridfs_file_flush_page (file); } else { _mongoc_gridfs_file_page_destroy (file->page); file->page = NULL; } } /** we'll pick up the seek when we fetch a page on the next action. We lazily load */ } else if (file->page) { _mongoc_gridfs_file_page_seek (file->page, offset % file->chunk_size); } file->pos = offset; file->n = file->pos / file->chunk_size; return 0; } uint64_t mongoc_gridfs_file_tell (mongoc_gridfs_file_t *file) { BSON_ASSERT(file); return file->pos; } bool mongoc_gridfs_file_error (mongoc_gridfs_file_t *file, bson_error_t *error) { BSON_ASSERT(file); BSON_ASSERT(error); if (BSON_UNLIKELY(file->error.domain)) { bson_set_error(error, file->error.domain, file->error.code, "%s", file->error.message); RETURN(true); } RETURN(false); } const bson_value_t * mongoc_gridfs_file_get_id (mongoc_gridfs_file_t *file) { BSON_ASSERT (file); return &file->files_id; } int64_t mongoc_gridfs_file_get_length (mongoc_gridfs_file_t *file) { BSON_ASSERT (file); return file->length; } int32_t mongoc_gridfs_file_get_chunk_size (mongoc_gridfs_file_t *file) { BSON_ASSERT (file); return file->chunk_size; } int64_t mongoc_gridfs_file_get_upload_date (mongoc_gridfs_file_t *file) { BSON_ASSERT (file); return file->upload_date; } bool mongoc_gridfs_file_remove (mongoc_gridfs_file_t *file, bson_error_t *error) { bson_t sel = BSON_INITIALIZER; bool ret = false; BSON_ASSERT (file); BSON_APPEND_VALUE (&sel, "_id", &file->files_id); if (!mongoc_collection_remove (file->gridfs->files, MONGOC_REMOVE_SINGLE_REMOVE, &sel, NULL, error)) { goto cleanup; } bson_reinit (&sel); BSON_APPEND_VALUE (&sel, "files_id", &file->files_id); if (!mongoc_collection_remove (file->gridfs->chunks, MONGOC_REMOVE_NONE, &sel, NULL, error)) { goto cleanup; } ret = true; cleanup: bson_destroy (&sel); return ret; } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-gridfs-file.h0000664000175000017500000000647612673034026023460 0ustar jmikolajmikola/* * Copyright 2013 MongoDB Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_GRIDFS_FILE_H #define MONGOC_GRIDFS_FILE_H #if !defined (MONGOC_INSIDE) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #include #include "mongoc-socket.h" BSON_BEGIN_DECLS #define MONGOC_GRIDFS_FILE_STR_HEADER(name) \ const char * \ mongoc_gridfs_file_get_##name (mongoc_gridfs_file_t * file); \ void \ mongoc_gridfs_file_set_##name (mongoc_gridfs_file_t * file, \ const char *str); #define MONGOC_GRIDFS_FILE_BSON_HEADER(name) \ const bson_t * \ mongoc_gridfs_file_get_##name (mongoc_gridfs_file_t * file); \ void \ mongoc_gridfs_file_set_##name (mongoc_gridfs_file_t * file, \ const bson_t * bson); typedef struct _mongoc_gridfs_file_t mongoc_gridfs_file_t; typedef struct _mongoc_gridfs_file_opt_t mongoc_gridfs_file_opt_t; struct _mongoc_gridfs_file_opt_t { const char *md5; const char *filename; const char *content_type; const bson_t *aliases; const bson_t *metadata; uint32_t chunk_size; }; MONGOC_GRIDFS_FILE_STR_HEADER (md5) MONGOC_GRIDFS_FILE_STR_HEADER (filename) MONGOC_GRIDFS_FILE_STR_HEADER (content_type) MONGOC_GRIDFS_FILE_BSON_HEADER (aliases) MONGOC_GRIDFS_FILE_BSON_HEADER (metadata) const bson_value_t * mongoc_gridfs_file_get_id (mongoc_gridfs_file_t * file); int64_t mongoc_gridfs_file_get_length (mongoc_gridfs_file_t *file); int32_t mongoc_gridfs_file_get_chunk_size (mongoc_gridfs_file_t *file); int64_t mongoc_gridfs_file_get_upload_date (mongoc_gridfs_file_t *file); ssize_t mongoc_gridfs_file_writev (mongoc_gridfs_file_t *file, mongoc_iovec_t *iov, size_t iovcnt, uint32_t timeout_msec); ssize_t mongoc_gridfs_file_readv (mongoc_gridfs_file_t *file, mongoc_iovec_t *iov, size_t iovcnt, size_t min_bytes, uint32_t timeout_msec); int mongoc_gridfs_file_seek (mongoc_gridfs_file_t *file, int64_t delta, int whence); uint64_t mongoc_gridfs_file_tell (mongoc_gridfs_file_t *file); bool mongoc_gridfs_file_save (mongoc_gridfs_file_t *file); void mongoc_gridfs_file_destroy (mongoc_gridfs_file_t *file); bool mongoc_gridfs_file_error (mongoc_gridfs_file_t *file, bson_error_t *error); bool mongoc_gridfs_file_remove (mongoc_gridfs_file_t *file, bson_error_t *error); BSON_END_DECLS #endif /* MONGOC_GRIDFS_FILE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-gridfs-private.h0000664000175000017500000000250212673034026024175 0ustar jmikolajmikola/* * Copyright 2013 MongoDB Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_GRIDFS_PRIVATE_H #define MONGOC_GRIDFS_PRIVATE_H #if !defined (MONGOC_I_AM_A_DRIVER) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #include #include "mongoc-read-prefs.h" #include "mongoc-write-concern.h" #include "mongoc-client.h" BSON_BEGIN_DECLS struct _mongoc_gridfs_t { mongoc_client_t *client; mongoc_collection_t *files; mongoc_collection_t *chunks; }; mongoc_gridfs_t *_mongoc_gridfs_new (mongoc_client_t *client, const char *db, const char *prefix, bson_error_t *error); BSON_END_DECLS #endif /* MONGOC_GRIDFS_PRIVATE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-gridfs.c0000664000175000017500000002366512673034026022535 0ustar jmikolajmikola/* * Copyright 2013 MongoDB Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "gridfs" #include "mongoc-bulk-operation.h" #include "mongoc-client-private.h" #include "mongoc-collection.h" #include "mongoc-collection-private.h" #include "mongoc-error.h" #include "mongoc-index.h" #include "mongoc-gridfs.h" #include "mongoc-gridfs-private.h" #include "mongoc-gridfs-file.h" #include "mongoc-gridfs-file-private.h" #include "mongoc-gridfs-file-list.h" #include "mongoc-gridfs-file-list-private.h" #include "mongoc-client.h" #include "mongoc-trace.h" #define MONGOC_GRIDFS_STREAM_CHUNK 4096 /** * _mongoc_gridfs_ensure_index: * * ensure gridfs indexes * * Ensure fast searches for chunks via [ files_id, n ] * Ensure fast searches for files via [ filename ] */ static bool _mongoc_gridfs_ensure_index (mongoc_gridfs_t *gridfs, bson_error_t *error) { bson_t keys; mongoc_index_opt_t opt; bool r; ENTRY; bson_init (&keys); bson_append_int32 (&keys, "files_id", -1, 1); bson_append_int32 (&keys, "n", -1, 1); mongoc_index_opt_init (&opt); opt.unique = 1; r = mongoc_collection_create_index (gridfs->chunks, &keys, &opt, error); bson_destroy (&keys); if (!r) { RETURN (r); } bson_init (&keys); bson_append_int32 (&keys, "filename", -1, 1); opt.unique = 0; r = mongoc_collection_create_index (gridfs->chunks, &keys, &opt, error); bson_destroy (&keys); if (!r) { RETURN (r); } RETURN (1); } mongoc_gridfs_t * _mongoc_gridfs_new (mongoc_client_t *client, const char *db, const char *prefix, bson_error_t *error) { mongoc_gridfs_t *gridfs; const mongoc_read_prefs_t *read_prefs; const mongoc_read_concern_t *read_concern; const mongoc_write_concern_t *write_concern; char buf[128]; bool r; ENTRY; BSON_ASSERT (client); BSON_ASSERT (db); if (!prefix) { prefix = "fs"; } /* make sure prefix is short enough to bucket the chunks and files * collections */ #ifndef BSON_DISABLE_ASSERT { uint32_t prefix_len; prefix_len = (uint32_t)strlen (prefix); BSON_ASSERT (prefix_len + sizeof (".chunks") < sizeof (buf)); } #endif gridfs = (mongoc_gridfs_t *) bson_malloc0 (sizeof *gridfs); gridfs->client = client; read_prefs = mongoc_client_get_read_prefs (client); read_concern = mongoc_client_get_read_concern (client); write_concern = mongoc_client_get_write_concern (client); bson_snprintf (buf, sizeof(buf), "%s.chunks", prefix); gridfs->chunks = _mongoc_collection_new (client, db, buf, read_prefs, read_concern, write_concern); bson_snprintf (buf, sizeof(buf), "%s.files", prefix); gridfs->files = _mongoc_collection_new (client, db, buf, read_prefs, read_concern, write_concern); r = _mongoc_gridfs_ensure_index (gridfs, error); if (!r) { mongoc_gridfs_destroy (gridfs); RETURN (NULL); } RETURN (gridfs); } bool mongoc_gridfs_drop (mongoc_gridfs_t *gridfs, bson_error_t *error) { bool r; ENTRY; r = mongoc_collection_drop (gridfs->files, error); if (!r) { RETURN (0); } r = mongoc_collection_drop (gridfs->chunks, error); if (!r) { RETURN (0); } RETURN (1); } void mongoc_gridfs_destroy (mongoc_gridfs_t *gridfs) { ENTRY; BSON_ASSERT (gridfs); mongoc_collection_destroy (gridfs->files); mongoc_collection_destroy (gridfs->chunks); bson_free (gridfs); EXIT; } /** find all matching gridfs files */ mongoc_gridfs_file_list_t * mongoc_gridfs_find (mongoc_gridfs_t *gridfs, const bson_t *query) { return _mongoc_gridfs_file_list_new (gridfs, query, 0); } /** find a single gridfs file */ mongoc_gridfs_file_t * mongoc_gridfs_find_one (mongoc_gridfs_t *gridfs, const bson_t *query, bson_error_t *error) { mongoc_gridfs_file_list_t *list; mongoc_gridfs_file_t *file; ENTRY; list = _mongoc_gridfs_file_list_new (gridfs, query, 1); file = mongoc_gridfs_file_list_next (list); mongoc_gridfs_file_list_error(list, error); mongoc_gridfs_file_list_destroy (list); RETURN (file); } /** find a single gridfs file by filename */ mongoc_gridfs_file_t * mongoc_gridfs_find_one_by_filename (mongoc_gridfs_t *gridfs, const char *filename, bson_error_t *error) { mongoc_gridfs_file_t *file; bson_t query; bson_init (&query); bson_append_utf8 (&query, "filename", -1, filename, -1); file = mongoc_gridfs_find_one (gridfs, &query, error); bson_destroy (&query); return file; } /** create a gridfs file from a stream * * The stream is fully consumed in creating the file */ mongoc_gridfs_file_t * mongoc_gridfs_create_file_from_stream (mongoc_gridfs_t *gridfs, mongoc_stream_t *stream, mongoc_gridfs_file_opt_t *opt) { mongoc_gridfs_file_t *file; ssize_t r; uint8_t buf[MONGOC_GRIDFS_STREAM_CHUNK]; mongoc_iovec_t iov; int timeout; ENTRY; BSON_ASSERT (gridfs); BSON_ASSERT (stream); iov.iov_base = (void *)buf; iov.iov_len = 0; file = _mongoc_gridfs_file_new (gridfs, opt); timeout = gridfs->client->cluster.sockettimeoutms; for (;; ) { r = mongoc_stream_read (stream, iov.iov_base, MONGOC_GRIDFS_STREAM_CHUNK, 0, timeout); if (r > 0) { iov.iov_len = r; mongoc_gridfs_file_writev (file, &iov, 1, timeout); } else if (r == 0) { break; } else { mongoc_gridfs_file_destroy (file); RETURN (NULL); } } mongoc_stream_failed (stream); mongoc_gridfs_file_seek (file, 0, SEEK_SET); RETURN (file); } /** create an empty gridfs file */ mongoc_gridfs_file_t * mongoc_gridfs_create_file (mongoc_gridfs_t *gridfs, mongoc_gridfs_file_opt_t *opt) { mongoc_gridfs_file_t *file; ENTRY; BSON_ASSERT (gridfs); file = _mongoc_gridfs_file_new (gridfs, opt); RETURN (file); } /** accessor functions for collections */ mongoc_collection_t * mongoc_gridfs_get_files (mongoc_gridfs_t *gridfs) { BSON_ASSERT (gridfs); return gridfs->files; } mongoc_collection_t * mongoc_gridfs_get_chunks (mongoc_gridfs_t *gridfs) { BSON_ASSERT (gridfs); return gridfs->chunks; } bool mongoc_gridfs_remove_by_filename (mongoc_gridfs_t *gridfs, const char *filename, bson_error_t *error) { mongoc_bulk_operation_t *bulk_files = NULL; mongoc_bulk_operation_t *bulk_chunks = NULL; mongoc_cursor_t *cursor = NULL; bson_error_t files_error; bson_error_t chunks_error; const bson_t *doc; const char *key; char keybuf[16]; int count = 0; bool chunks_ret; bool files_ret; bool ret = false; bson_iter_t iter; bson_t *files_q = NULL; bson_t *chunks_q = NULL; bson_t q = BSON_INITIALIZER; bson_t fields = BSON_INITIALIZER; bson_t ar = BSON_INITIALIZER; BSON_ASSERT (gridfs); if (!filename) { bson_set_error (error, MONGOC_ERROR_GRIDFS, MONGOC_ERROR_GRIDFS_INVALID_FILENAME, "A non-NULL filename must be specified."); return false; } /* * Find all files matching this filename. Hopefully just one, but not * strictly required! */ BSON_APPEND_UTF8 (&q, "filename", filename); BSON_APPEND_INT32 (&fields, "_id", 1); cursor = mongoc_collection_find (gridfs->files, MONGOC_QUERY_NONE, 0, 0, 0, &q, &fields, NULL); BSON_ASSERT (cursor); while (mongoc_cursor_next (cursor, &doc)) { if (bson_iter_init_find (&iter, doc, "_id")) { const bson_value_t *value = bson_iter_value (&iter); bson_uint32_to_string (count, &key, keybuf, sizeof keybuf); BSON_APPEND_VALUE (&ar, key, value); } } if (mongoc_cursor_error (cursor, error)) { goto failure; } bulk_files = mongoc_collection_create_bulk_operation (gridfs->files, false, NULL); bulk_chunks = mongoc_collection_create_bulk_operation (gridfs->chunks, false, NULL); files_q = BCON_NEW ("_id", "{", "$in", BCON_ARRAY (&ar), "}"); chunks_q = BCON_NEW ("files_id", "{", "$in", BCON_ARRAY (&ar), "}"); mongoc_bulk_operation_remove (bulk_files, files_q); mongoc_bulk_operation_remove (bulk_chunks, chunks_q); files_ret = mongoc_bulk_operation_execute (bulk_files, NULL, &files_error); chunks_ret = mongoc_bulk_operation_execute (bulk_chunks, NULL, &chunks_error); if (error) { if (!files_ret) { memcpy (error, &files_error, sizeof *error); } else if (!chunks_ret) { memcpy (error, &chunks_error, sizeof *error); } } ret = (files_ret && chunks_ret); failure: if (cursor) { mongoc_cursor_destroy (cursor); } if (bulk_files) { mongoc_bulk_operation_destroy (bulk_files); } if (bulk_chunks) { mongoc_bulk_operation_destroy (bulk_chunks); } bson_destroy (&q); bson_destroy (&fields); bson_destroy (&ar); if (files_q) { bson_destroy (files_q); } if (chunks_q) { bson_destroy (chunks_q); } return ret; } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-gridfs.h0000664000175000017500000000607612673034026022537 0ustar jmikolajmikola/* * Copyright 2013 MongoDB Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_GRIDFS_H #define MONGOC_GRIDFS_H #if !defined (MONGOC_INSIDE) && !defined (MONGOC_COMPILATION) # error "Only can be included directly." #endif #include #include "mongoc-stream.h" #include "mongoc-gridfs-file.h" #include "mongoc-collection.h" #include "mongoc-gridfs-file-list.h" BSON_BEGIN_DECLS typedef struct _mongoc_gridfs_t mongoc_gridfs_t; mongoc_gridfs_file_t *mongoc_gridfs_create_file_from_stream (mongoc_gridfs_t *gridfs, mongoc_stream_t *stream, mongoc_gridfs_file_opt_t *opt); mongoc_gridfs_file_t *mongoc_gridfs_create_file (mongoc_gridfs_t *gridfs, mongoc_gridfs_file_opt_t *opt); mongoc_gridfs_file_list_t *mongoc_gridfs_find (mongoc_gridfs_t *gridfs, const bson_t *query); mongoc_gridfs_file_t *mongoc_gridfs_find_one (mongoc_gridfs_t *gridfs, const bson_t *query, bson_error_t *error); mongoc_gridfs_file_t *mongoc_gridfs_find_one_by_filename (mongoc_gridfs_t *gridfs, const char *filename, bson_error_t *error); bool mongoc_gridfs_drop (mongoc_gridfs_t *gridfs, bson_error_t *error); void mongoc_gridfs_destroy (mongoc_gridfs_t *gridfs); mongoc_collection_t *mongoc_gridfs_get_files (mongoc_gridfs_t *gridfs); mongoc_collection_t *mongoc_gridfs_get_chunks (mongoc_gridfs_t *gridfs); bool mongoc_gridfs_remove_by_filename (mongoc_gridfs_t *gridfs, const char *filename, bson_error_t *error); BSON_END_DECLS #endif /* MONGOC_GRIDFS_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-host-list-private.h0000664000175000017500000000232512673034026024650 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_HOST_LIST_PRIVATE_H #define MONGOC_HOST_LIST_PRIVATE_H #if !defined (MONGOC_I_AM_A_DRIVER) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #include "mongoc-host-list.h" BSON_BEGIN_DECLS bool _mongoc_host_list_from_string (mongoc_host_list_t *host_list, const char *host_and_port); bool _mongoc_host_list_equal (const mongoc_host_list_t *host_a, const mongoc_host_list_t *host_b); void _mongoc_host_list_destroy_all (mongoc_host_list_t *host); BSON_END_DECLS #endif /* MONGOC_HOST_LIST_PRIVATE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-host-list.c0000664000175000017500000000326312673034026023175 0ustar jmikolajmikola/* * Copyright 2015 MongoDB Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "mongoc-host-list-private.h" /* strcasecmp on windows */ #include "mongoc-util-private.h" /* *-------------------------------------------------------------------------- * * _mongoc_host_list_equal -- * * Check two hosts have the same domain (case-insensitive), port, * and address family. * * Side effects: * None. * *-------------------------------------------------------------------------- */ bool _mongoc_host_list_equal (const mongoc_host_list_t *host_a, const mongoc_host_list_t *host_b) { return (!strcasecmp (host_a->host_and_port, host_b->host_and_port) && host_a->family == host_b->family); } /* *-------------------------------------------------------------------------- * * _mongoc_host_list_destroy_all -- * * Destroy whole linked list of hosts. * *-------------------------------------------------------------------------- */ void _mongoc_host_list_destroy_all (mongoc_host_list_t *host) { mongoc_host_list_t *tmp; while (host) { tmp = host->next; bson_free (host); host = tmp; } } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-host-list.h0000664000175000017500000000256712673034026023210 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_HOST_LIST_H #define MONGOC_HOST_LIST_H #if !defined (MONGOC_INSIDE) && !defined (MONGOC_COMPILATION) # error "Only can be included directly." #endif #include BSON_BEGIN_DECLS #ifndef HOST_NAME_MAX # ifdef _POSIX_HOST_NAME_MAX # define BSON_HOST_NAME_MAX _POSIX_HOST_NAME_MAX # else # define BSON_HOST_NAME_MAX 255 # endif #else # define BSON_HOST_NAME_MAX HOST_NAME_MAX #endif typedef struct _mongoc_host_list_t mongoc_host_list_t; struct _mongoc_host_list_t { mongoc_host_list_t *next; char host [BSON_HOST_NAME_MAX + 1]; char host_and_port [BSON_HOST_NAME_MAX + 7]; uint16_t port; int family; void *padding [4]; }; BSON_END_DECLS #endif /* MONGOC_HOST_LIST_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-index.c0000664000175000017500000000553212673034026022357 0ustar jmikolajmikola/* * Copyright 2013 MongoDB Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "mongoc-index.h" #include "mongoc-trace.h" #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "gridfs_index" static mongoc_index_opt_t gMongocIndexOptDefault = { 1, /* is_initialized */ 0, /* background */ 0, /* unique */ NULL, /* name */ 0, /* drop_dups */ 0, /* sparse */ -1, /* expire_after_seconds */ -1, /* v */ NULL, /* weights */ NULL, /* default_language */ NULL, /* language_override */ NULL, /* mongoc_index_opt_geo_t geo_options */ NULL, /* mongoc_index_opt_storage_t storage_options */ NULL, /* partial_filter_expression */ {NULL} /* struct padding */ }; static mongoc_index_opt_geo_t gMongocIndexOptGeoDefault = { 26, /* twod_sphere_version */ -90, /* twod_bits_precision */ 90, /* twod_location_min */ -1, /* twod_location_max */ 2, /* haystack_bucket_size */ {NULL} /* struct padding */ }; static mongoc_index_opt_wt_t gMongocIndexOptWTDefault = { { MONGOC_INDEX_STORAGE_OPT_WIREDTIGER }, /* mongoc_index_opt_storage_t */ "", /* config_str */ {NULL} /* struct padding */ }; const mongoc_index_opt_t * mongoc_index_opt_get_default (void) { return &gMongocIndexOptDefault; } const mongoc_index_opt_geo_t * mongoc_index_opt_geo_get_default (void) { return &gMongocIndexOptGeoDefault; } const mongoc_index_opt_wt_t * mongoc_index_opt_wt_get_default (void) { return &gMongocIndexOptWTDefault; } void mongoc_index_opt_init (mongoc_index_opt_t *opt) { BSON_ASSERT (opt); memcpy (opt, &gMongocIndexOptDefault, sizeof *opt); } void mongoc_index_opt_geo_init (mongoc_index_opt_geo_t *opt) { BSON_ASSERT (opt); memcpy (opt, &gMongocIndexOptGeoDefault, sizeof *opt); } void mongoc_index_opt_wt_init (mongoc_index_opt_wt_t *opt) { BSON_ASSERT(opt); memcpy (opt, &gMongocIndexOptWTDefault, sizeof *opt); } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-index.h0000664000175000017500000000516112673034026022362 0ustar jmikolajmikola/* * Copyright 2013 MongoDB Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_INDEX_H #define MONGOC_INDEX_H #if !defined (MONGOC_INSIDE) && !defined (MONGOC_COMPILATION) # error "Only can be included directly." #endif #include BSON_BEGIN_DECLS typedef struct { uint8_t twod_sphere_version; uint8_t twod_bits_precision; double twod_location_min; double twod_location_max; double haystack_bucket_size; uint8_t *padding[32]; } mongoc_index_opt_geo_t; typedef struct { int type; } mongoc_index_opt_storage_t; typedef enum { MONGOC_INDEX_STORAGE_OPT_MMAPV1, MONGOC_INDEX_STORAGE_OPT_WIREDTIGER, } mongoc_index_storage_opt_type_t; typedef struct { mongoc_index_opt_storage_t base; const char *config_str; void *padding[8]; } mongoc_index_opt_wt_t; typedef struct { bool is_initialized; bool background; bool unique; const char *name; bool drop_dups; bool sparse; int32_t expire_after_seconds; int32_t v; const bson_t *weights; const char *default_language; const char *language_override; mongoc_index_opt_geo_t *geo_options; mongoc_index_opt_storage_t *storage_options; const bson_t *partial_filter_expression; void *padding[5]; } mongoc_index_opt_t; const mongoc_index_opt_t *mongoc_index_opt_get_default (void) BSON_GNUC_CONST; const mongoc_index_opt_geo_t *mongoc_index_opt_geo_get_default (void) BSON_GNUC_CONST; const mongoc_index_opt_wt_t *mongoc_index_opt_wt_get_default (void) BSON_GNUC_CONST; void mongoc_index_opt_init (mongoc_index_opt_t *opt); void mongoc_index_opt_geo_init (mongoc_index_opt_geo_t *opt); void mongoc_index_opt_wt_init (mongoc_index_opt_wt_t *opt); BSON_END_DECLS #endif /* MONGOC_INDEX_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-init.c0000664000175000017500000000662012673034026022212 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include "mongoc-config.h" #include "mongoc-counters-private.h" #include "mongoc-init.h" #ifdef MONGOC_ENABLE_SSL # include "mongoc-scram-private.h" # include "mongoc-ssl.h" # include "mongoc-ssl-private.h" #endif #include "mongoc-thread-private.h" #include "mongoc-trace.h" #ifdef MONGOC_ENABLE_SASL #include static void * mongoc_sasl_mutex_alloc (void) { mongoc_mutex_t *mutex; mutex = (mongoc_mutex_t *)bson_malloc0 (sizeof (mongoc_mutex_t)); mongoc_mutex_init (mutex); return (void *) mutex; } static int mongoc_sasl_mutex_lock (void *mutex) { mongoc_mutex_lock ((mongoc_mutex_t *) mutex); return SASL_OK; } static int mongoc_sasl_mutex_unlock (void *mutex) { mongoc_mutex_unlock ((mongoc_mutex_t *) mutex); return SASL_OK; } static void mongoc_sasl_mutex_free (void *mutex) { mongoc_mutex_destroy ((mongoc_mutex_t *) mutex); bson_free (mutex); } #endif//MONGOC_ENABLE_SASL static MONGOC_ONCE_FUN( _mongoc_do_init) { #ifdef MONGOC_ENABLE_SSL _mongoc_ssl_init(); _mongoc_scram_startup(); #endif #ifdef MONGOC_ENABLE_SASL /* The following functions should not use tracing, as they may be invoked * before mongoc_log_set_handler() can complete. */ sasl_set_mutex (mongoc_sasl_mutex_alloc, mongoc_sasl_mutex_lock, mongoc_sasl_mutex_unlock, mongoc_sasl_mutex_free); /* TODO: logging callback? */ sasl_client_init (NULL); #endif _mongoc_counters_init(); #ifdef _WIN32 { WORD wVersionRequested; WSADATA wsaData; int err; wVersionRequested = MAKEWORD (2, 2); err = WSAStartup (wVersionRequested, &wsaData); /* check the version perhaps? */ BSON_ASSERT (err == 0); } #endif MONGOC_ONCE_RETURN; } void mongoc_init (void) { static mongoc_once_t once = MONGOC_ONCE_INIT; mongoc_once (&once, _mongoc_do_init); } static MONGOC_ONCE_FUN( _mongoc_do_cleanup) { #ifdef MONGOC_ENABLE_SSL _mongoc_ssl_cleanup(); #endif #ifdef MONGOC_ENABLE_SASL #ifdef MONGOC_HAVE_SASL_CLIENT_DONE sasl_client_done (); #else /* fall back to deprecated function */ sasl_done (); #endif #endif #ifdef _WIN32 WSACleanup (); #endif _mongoc_counters_cleanup (); MONGOC_ONCE_RETURN; } void mongoc_cleanup (void) { static mongoc_once_t once = MONGOC_ONCE_INIT; mongoc_once (&once, _mongoc_do_cleanup); } /* * On GCC, just use __attribute__((constructor)) to perform initialization * automatically for the application. */ #if defined(__GNUC__) && ! defined(MONGOC_NO_AUTOMATIC_GLOBALS) static void _mongoc_init_ctor (void) __attribute__((constructor)); static void _mongoc_init_ctor (void) { mongoc_init (); } static void _mongoc_init_dtor (void) __attribute__((destructor)); static void _mongoc_init_dtor (void) { mongoc_cleanup (); } #endif mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-init.h0000664000175000017500000000160612673034026022216 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_INIT_H #define MONGOC_INIT_H #if !defined (MONGOC_INSIDE) && !defined (MONGOC_COMPILATION) # error "Only can be included directly." #endif #include BSON_BEGIN_DECLS void mongoc_init (void); void mongoc_cleanup(void); BSON_END_DECLS #endif /* MONGOC_INIT_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-iovec.h0000664000175000017500000000221612673034026022356 0ustar jmikolajmikola/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_IOVEC_H #define MONGOC_IOVEC_H #include #ifdef _WIN32 # include #else # include #endif BSON_BEGIN_DECLS #ifdef _WIN32 typedef struct { u_long iov_len; char *iov_base; } mongoc_iovec_t; BSON_STATIC_ASSERT(sizeof(mongoc_iovec_t) == sizeof(WSABUF)); BSON_STATIC_ASSERT(offsetof(mongoc_iovec_t, iov_base) == offsetof(WSABUF, buf)); BSON_STATIC_ASSERT(offsetof(mongoc_iovec_t, iov_len) == offsetof(WSABUF, len)); #else typedef struct iovec mongoc_iovec_t; #endif BSON_END_DECLS #endif /* MONGOC_IOVEC_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-list-private.h0000664000175000017500000000306712673034026023701 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_LIST_H #define MONGOC_LIST_H #if !defined (MONGOC_I_AM_A_DRIVER) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #include BSON_BEGIN_DECLS typedef struct _mongoc_list_t mongoc_list_t; struct _mongoc_list_t { mongoc_list_t *next; void *data; }; mongoc_list_t *_mongoc_list_append (mongoc_list_t *list, void *data); mongoc_list_t *_mongoc_list_prepend (mongoc_list_t *list, void *data); mongoc_list_t *_mongoc_list_remove (mongoc_list_t *list, void *data); void _mongoc_list_foreach (mongoc_list_t *list, void (*func) (void *data, void *user_data), void * user_data); void _mongoc_list_destroy (mongoc_list_t *list); BSON_END_DECLS #endif /* MONGOC_LIST_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-list.c0000664000175000017500000000616712673034026022230 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "mongoc-list-private.h" /** * mongoc_list_append: * @list: A list to append to, or NULL. * @data: Data to append to @list. * * Appends a new link onto the linked list. * * Returns: @list or a new list if @list is NULL. */ mongoc_list_t * _mongoc_list_append (mongoc_list_t *list, void *data) { mongoc_list_t *item; mongoc_list_t *iter; item = (mongoc_list_t *)bson_malloc0(sizeof *item); item->data = (void *)data; if (!list) { return item; } for (iter = list; iter->next; iter = iter->next) { } iter->next = item; return list; } /** * mongoc_list_prepend: * @list: A mongoc_list_t or NULL. * @data: data to prepend to the list. * * Prepends to @list a new link containing @data. * * Returns: A new link containing data with @list following. */ mongoc_list_t * _mongoc_list_prepend (mongoc_list_t *list, void *data) { mongoc_list_t *item; item = (mongoc_list_t *)bson_malloc0(sizeof *item); item->data = (void *)data; item->next = list; return item; } /** * mongoc_list_remove: * @list: A mongoc_list_t. * @data: Data to remove from @list. * * Removes the link containing @data from @list. * * Returns: @list with the link containing @data removed. */ mongoc_list_t * _mongoc_list_remove (mongoc_list_t *list, void *data) { mongoc_list_t *iter; mongoc_list_t *prev = NULL; mongoc_list_t *ret = list; BSON_ASSERT (list); for (iter = list; iter; iter = iter->next) { if (iter->data == data) { if (iter != list) { prev->next = iter->next; } else { ret = iter->next; } bson_free(iter); break; } prev = iter; } return ret; } /** * mongoc_list_foreach: * @list: A mongoc_list_t or NULL. * @func: A func to call for each link in @list. * @user_data: User data for @func. * * Calls @func for each item in @list. */ void _mongoc_list_foreach (mongoc_list_t *list, void (*func) (void *data, void *user_data), void *user_data) { mongoc_list_t *iter; BSON_ASSERT (func); for (iter = list; iter; iter = iter->next) { func(iter->data, user_data); } } /** * mongoc_list_destroy: * @list: A mongoc_list_t. * * Destroys @list and releases any resources. */ void _mongoc_list_destroy (mongoc_list_t *list) { mongoc_list_t *tmp = list; while (list) { tmp = list->next; bson_free(list); list = tmp; } } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-log-private.h0000664000175000017500000000266212673034026023507 0ustar jmikolajmikola/* * Copyright 2015 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_LOG_PRIVATE_H #define MONGOC_LOG_PRIVATE_H #if !defined (MONGOC_INSIDE) && !defined (MONGOC_COMPILATION) && !defined (MONGOC_I_AM_A_DRIVER) # error "Only can be included directly." #endif #include "mongoc-iovec.h" /* just for testing */ void _mongoc_log_get_handler (mongoc_log_func_t *log_func, void **user_data); bool _mongoc_log_trace_is_enabled (void); void mongoc_log_trace_bytes (const char *domain, const uint8_t *_b, size_t _l); void mongoc_log_trace_iovec (const char *domain, const mongoc_iovec_t *_iov, size_t _iovcnt); void mongoc_log_trace_enable (void); void mongoc_log_trace_disable (void); #endif /* MONGOC_LOG_PRIVATE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-log.c0000664000175000017500000001613512673034026022032 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if defined(__linux__) # include #elif defined(_WIN32) # include #else # include #endif #include #include #include "mongoc-log.h" #include "mongoc-log-private.h" #include "mongoc-thread-private.h" static mongoc_mutex_t gLogMutex; static mongoc_log_func_t gLogFunc = mongoc_log_default_handler; #ifdef MONGOC_TRACE static bool gLogTrace = true; #endif static void *gLogData; static MONGOC_ONCE_FUN( _mongoc_ensure_mutex_once) { mongoc_mutex_init(&gLogMutex); MONGOC_ONCE_RETURN; } void mongoc_log_set_handler (mongoc_log_func_t log_func, void *user_data) { static mongoc_once_t once = MONGOC_ONCE_INIT; mongoc_once(&once, &_mongoc_ensure_mutex_once); mongoc_mutex_lock(&gLogMutex); gLogFunc = log_func; gLogData = user_data; mongoc_mutex_unlock(&gLogMutex); } /* just for testing */ void _mongoc_log_get_handler (mongoc_log_func_t *log_func, void **user_data) { *log_func = gLogFunc; *user_data = gLogData; } void mongoc_log (mongoc_log_level_t log_level, const char *log_domain, const char *format, ...) { va_list args; char *message; static mongoc_once_t once = MONGOC_ONCE_INIT; int stop_logging; mongoc_once(&once, &_mongoc_ensure_mutex_once); stop_logging = !gLogFunc; #ifdef MONGOC_TRACE stop_logging = stop_logging || (log_level == MONGOC_LOG_LEVEL_TRACE && !gLogTrace); #endif if (stop_logging) { return; } BSON_ASSERT (format); va_start(args, format); message = bson_strdupv_printf(format, args); va_end(args); mongoc_mutex_lock(&gLogMutex); gLogFunc(log_level, log_domain, message, gLogData); mongoc_mutex_unlock(&gLogMutex); bson_free(message); } const char * mongoc_log_level_str (mongoc_log_level_t log_level) { switch (log_level) { case MONGOC_LOG_LEVEL_ERROR: return "ERROR"; case MONGOC_LOG_LEVEL_CRITICAL: return "CRITICAL"; case MONGOC_LOG_LEVEL_WARNING: return "WARNING"; case MONGOC_LOG_LEVEL_MESSAGE: return "MESSAGE"; case MONGOC_LOG_LEVEL_INFO: return "INFO"; case MONGOC_LOG_LEVEL_DEBUG: return "DEBUG"; case MONGOC_LOG_LEVEL_TRACE: return "TRACE"; default: return "UNKNOWN"; } } void mongoc_log_default_handler (mongoc_log_level_t log_level, const char *log_domain, const char *message, void *user_data) { struct timeval tv; struct tm tt; time_t t; FILE *stream; char nowstr[32]; int pid; bson_gettimeofday(&tv); t = tv.tv_sec; #ifdef _WIN32 # ifdef _MSC_VER localtime_s(&tt, &t); # else tt = *(localtime(&t)); # endif #else localtime_r(&t, &tt); #endif strftime (nowstr, sizeof nowstr, "%Y/%m/%d %H:%M:%S", &tt); switch (log_level) { case MONGOC_LOG_LEVEL_ERROR: case MONGOC_LOG_LEVEL_CRITICAL: case MONGOC_LOG_LEVEL_WARNING: stream = stderr; break; case MONGOC_LOG_LEVEL_MESSAGE: case MONGOC_LOG_LEVEL_INFO: case MONGOC_LOG_LEVEL_DEBUG: case MONGOC_LOG_LEVEL_TRACE: default: stream = stdout; } #ifdef __linux__ pid = syscall (SYS_gettid); #elif defined(_WIN32) pid = (int)_getpid (); #else pid = (int)getpid (); #endif fprintf (stream, "%s.%04ld: [%5d]: %8s: %12s: %s\n", nowstr, tv.tv_usec / 1000L, pid, mongoc_log_level_str(log_level), log_domain, message); } bool _mongoc_log_trace_is_enabled (void) { #ifdef MONGOC_TRACE return gLogTrace; #else return false; #endif } void mongoc_log_trace_enable (void) { #ifdef MONGOC_TRACE gLogTrace = true; #endif } void mongoc_log_trace_disable (void) { #ifdef MONGOC_TRACE gLogTrace = false; #endif } void mongoc_log_trace_bytes (const char *domain, const uint8_t *_b, size_t _l) { bson_string_t *str, *astr; int32_t _i; uint8_t _v; #ifdef MONGOC_TRACE if (!gLogTrace) { return; } #endif str = bson_string_new(NULL); astr = bson_string_new(NULL); for (_i = 0; _i < _l; _i++) { _v = *(_b + _i); if ((_i % 16) == 0) { bson_string_append_printf(str, "%05x: ", _i); } bson_string_append_printf(str, " %02x", _v); if (isprint(_v)) { bson_string_append_printf(astr, " %c", _v); } else { bson_string_append(astr, " ."); } if ((_i % 16) == 15) { mongoc_log(MONGOC_LOG_LEVEL_TRACE, domain, "%s %s", str->str, astr->str); bson_string_truncate(str, 0); bson_string_truncate(astr, 0); } else if ((_i % 16) == 7) { bson_string_append(str, " "); bson_string_append(astr, " "); } } if (_i != 16) { mongoc_log(MONGOC_LOG_LEVEL_TRACE, domain, "%-56s %s", str->str, astr->str); } bson_string_free(str, true); bson_string_free(astr, true); } void mongoc_log_trace_iovec (const char *domain, const mongoc_iovec_t *_iov, size_t _iovcnt) { bson_string_t *str, *astr; const char *_b; unsigned _i = 0; unsigned _j = 0; unsigned _k = 0; size_t _l = 0; uint8_t _v; #ifdef MONGOC_TRACE if (!gLogTrace) { return; } #endif for (_i = 0; _i < _iovcnt; _i++) { _l += _iov[_i].iov_len; } _i = 0; str = bson_string_new(NULL); astr = bson_string_new(NULL); for (_j = 0; _j < _iovcnt; _j++) { _b = (char *)_iov[_j].iov_base; _l = _iov[_j].iov_len; for (_k = 0; _k < _l; _k++, _i++) { _v = *(_b + _k); if ((_i % 16) == 0) { bson_string_append_printf(str, "%05x: ", _i); } bson_string_append_printf(str, " %02x", _v); if (isprint(_v)) { bson_string_append_printf(astr, " %c", _v); } else { bson_string_append(astr, " ."); } if ((_i % 16) == 15) { mongoc_log(MONGOC_LOG_LEVEL_TRACE, domain, "%s %s", str->str, astr->str); bson_string_truncate(str, 0); bson_string_truncate(astr, 0); } else if ((_i % 16) == 7) { bson_string_append(str, " "); bson_string_append(astr, " "); } } } if (_i != 16) { mongoc_log(MONGOC_LOG_LEVEL_TRACE, domain, "%-56s %s", str->str, astr->str); } bson_string_free(str, true); bson_string_free(astr, true); } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-log.h0000664000175000017500000000734612673034026022043 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_LOG_H #define MONGOC_LOG_H #if !defined (MONGOC_INSIDE) && !defined (MONGOC_COMPILATION) # error "Only can be included directly." #endif #include BSON_BEGIN_DECLS #ifndef MONGOC_LOG_DOMAIN # define MONGOC_LOG_DOMAIN "mongoc" #endif #define MONGOC_ERROR(...) mongoc_log(MONGOC_LOG_LEVEL_ERROR, MONGOC_LOG_DOMAIN, __VA_ARGS__) #define MONGOC_CRITICAL(...) mongoc_log(MONGOC_LOG_LEVEL_CRITICAL, MONGOC_LOG_DOMAIN, __VA_ARGS__) #define MONGOC_WARNING(...) mongoc_log(MONGOC_LOG_LEVEL_WARNING, MONGOC_LOG_DOMAIN, __VA_ARGS__) #define MONGOC_MESSAGE(...) mongoc_log(MONGOC_LOG_LEVEL_MESSAGE, MONGOC_LOG_DOMAIN, __VA_ARGS__) #define MONGOC_INFO(...) mongoc_log(MONGOC_LOG_LEVEL_INFO, MONGOC_LOG_DOMAIN, __VA_ARGS__) #define MONGOC_DEBUG(...) mongoc_log(MONGOC_LOG_LEVEL_DEBUG, MONGOC_LOG_DOMAIN, __VA_ARGS__) typedef enum { MONGOC_LOG_LEVEL_ERROR, MONGOC_LOG_LEVEL_CRITICAL, MONGOC_LOG_LEVEL_WARNING, MONGOC_LOG_LEVEL_MESSAGE, MONGOC_LOG_LEVEL_INFO, MONGOC_LOG_LEVEL_DEBUG, MONGOC_LOG_LEVEL_TRACE, } mongoc_log_level_t; /** * mongoc_log_func_t: * @log_level: The level of the log message. * @log_domain: The domain of the log message, such as "client". * @message: The message generated. * @user_data: User data provided to mongoc_log_set_handler(). * * This function prototype can be used to set a custom log handler for the * libmongoc library. This is useful if you would like to show them in a * user interface or alternate storage. */ typedef void (*mongoc_log_func_t) (mongoc_log_level_t log_level, const char *log_domain, const char *message, void *user_data); /** * mongoc_log_set_handler: * @log_func: A function to handle log messages. * @user_data: User data for @log_func. * * Sets the function to be called to handle logging. */ void mongoc_log_set_handler (mongoc_log_func_t log_func, void *user_data); /** * mongoc_log: * @log_level: The log level. * @log_domain: The log domain (such as "client"). * @format: The format string for the log message. * * Logs a message using the currently configured logger. * * This method will hold a logging lock to prevent concurrent calls to the * logging infrastructure. It is important that your configured log function * does not re-enter the logging system or deadlock will occur. * */ void mongoc_log (mongoc_log_level_t log_level, const char *log_domain, const char *format, ...) BSON_GNUC_PRINTF(3, 4); void mongoc_log_default_handler (mongoc_log_level_t log_level, const char *log_domain, const char *message, void *user_data); /** * mongoc_log_level_str: * @log_level: The log level. * * Returns: The string representation of log_level */ const char * mongoc_log_level_str (mongoc_log_level_t log_level); BSON_END_DECLS #endif /* MONGOC_LOG_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-matcher-op-private.h0000664000175000017500000001015512673034026024761 0ustar jmikolajmikola/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_MATCHER_OP_PRIVATE_H #define MONGOC_MATCHER_OP_PRIVATE_H #if !defined (MONGOC_I_AM_A_DRIVER) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #include BSON_BEGIN_DECLS typedef union _mongoc_matcher_op_t mongoc_matcher_op_t; typedef struct _mongoc_matcher_op_base_t mongoc_matcher_op_base_t; typedef struct _mongoc_matcher_op_logical_t mongoc_matcher_op_logical_t; typedef struct _mongoc_matcher_op_compare_t mongoc_matcher_op_compare_t; typedef struct _mongoc_matcher_op_exists_t mongoc_matcher_op_exists_t; typedef struct _mongoc_matcher_op_type_t mongoc_matcher_op_type_t; typedef struct _mongoc_matcher_op_not_t mongoc_matcher_op_not_t; typedef enum { MONGOC_MATCHER_OPCODE_EQ, MONGOC_MATCHER_OPCODE_GT, MONGOC_MATCHER_OPCODE_GTE, MONGOC_MATCHER_OPCODE_IN, MONGOC_MATCHER_OPCODE_LT, MONGOC_MATCHER_OPCODE_LTE, MONGOC_MATCHER_OPCODE_NE, MONGOC_MATCHER_OPCODE_NIN, MONGOC_MATCHER_OPCODE_OR, MONGOC_MATCHER_OPCODE_AND, MONGOC_MATCHER_OPCODE_NOT, MONGOC_MATCHER_OPCODE_NOR, MONGOC_MATCHER_OPCODE_EXISTS, MONGOC_MATCHER_OPCODE_TYPE, } mongoc_matcher_opcode_t; struct _mongoc_matcher_op_base_t { mongoc_matcher_opcode_t opcode; }; struct _mongoc_matcher_op_logical_t { mongoc_matcher_op_base_t base; mongoc_matcher_op_t *left; mongoc_matcher_op_t *right; }; struct _mongoc_matcher_op_compare_t { mongoc_matcher_op_base_t base; char *path; bson_iter_t iter; }; struct _mongoc_matcher_op_exists_t { mongoc_matcher_op_base_t base; char *path; bool exists; }; struct _mongoc_matcher_op_type_t { mongoc_matcher_op_base_t base; bson_type_t type; char *path; }; struct _mongoc_matcher_op_not_t { mongoc_matcher_op_base_t base; mongoc_matcher_op_t *child; char *path; }; union _mongoc_matcher_op_t { mongoc_matcher_op_base_t base; mongoc_matcher_op_logical_t logical; mongoc_matcher_op_compare_t compare; mongoc_matcher_op_exists_t exists; mongoc_matcher_op_type_t type; mongoc_matcher_op_not_t not_; }; mongoc_matcher_op_t *_mongoc_matcher_op_logical_new (mongoc_matcher_opcode_t opcode, mongoc_matcher_op_t *left, mongoc_matcher_op_t *right); mongoc_matcher_op_t *_mongoc_matcher_op_compare_new (mongoc_matcher_opcode_t opcode, const char *path, const bson_iter_t *iter); mongoc_matcher_op_t *_mongoc_matcher_op_exists_new (const char *path, bool exists); mongoc_matcher_op_t *_mongoc_matcher_op_type_new (const char *path, bson_type_t type); mongoc_matcher_op_t *_mongoc_matcher_op_not_new (const char *path, mongoc_matcher_op_t *child); bool _mongoc_matcher_op_match (mongoc_matcher_op_t *op, const bson_t *bson); void _mongoc_matcher_op_destroy (mongoc_matcher_op_t *op); void _mongoc_matcher_op_to_bson (mongoc_matcher_op_t *op, bson_t *bson); BSON_END_DECLS #endif /* MONGOC_MATCHER_OP_PRIVATE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-matcher-op.c0000664000175000017500000010257712673034026023316 0ustar jmikolajmikola/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "mongoc-log.h" #include "mongoc-matcher-op-private.h" #include "mongoc-util-private.h" /* *-------------------------------------------------------------------------- * * _mongoc_matcher_op_exists_new -- * * Create a new op for checking {$exists: bool}. * * Returns: * A newly allocated mongoc_matcher_op_t that should be freed with * _mongoc_matcher_op_destroy(). * * Side effects: * None. * *-------------------------------------------------------------------------- */ mongoc_matcher_op_t * _mongoc_matcher_op_exists_new (const char *path, /* IN */ bool exists) /* IN */ { mongoc_matcher_op_t *op; BSON_ASSERT (path); op = (mongoc_matcher_op_t *)bson_malloc0 (sizeof *op); op->exists.base.opcode = MONGOC_MATCHER_OPCODE_EXISTS; op->exists.path = bson_strdup (path); op->exists.exists = exists; return op; } /* *-------------------------------------------------------------------------- * * _mongoc_matcher_op_type_new -- * * Create a new op for checking {$type: int}. * * Returns: * A newly allocated mongoc_matcher_op_t that should be freed with * _mongoc_matcher_op_destroy(). * * Side effects: * None. * *-------------------------------------------------------------------------- */ mongoc_matcher_op_t * _mongoc_matcher_op_type_new (const char *path, /* IN */ bson_type_t type) /* IN */ { mongoc_matcher_op_t *op; BSON_ASSERT (path); BSON_ASSERT (type); op = (mongoc_matcher_op_t *)bson_malloc0 (sizeof *op); op->type.base.opcode = MONGOC_MATCHER_OPCODE_TYPE; op->type.path = bson_strdup (path); op->type.type = type; return op; } /* *-------------------------------------------------------------------------- * * _mongoc_matcher_op_logical_new -- * * Create a new op for checking any of: * * {$or: []} * {$nor: []} * {$and: []} * * Returns: * A newly allocated mongoc_matcher_op_t that should be freed with * _mongoc_matcher_op_destroy(). * * Side effects: * None. * *-------------------------------------------------------------------------- */ mongoc_matcher_op_t * _mongoc_matcher_op_logical_new (mongoc_matcher_opcode_t opcode, /* IN */ mongoc_matcher_op_t *left, /* IN */ mongoc_matcher_op_t *right) /* IN */ { mongoc_matcher_op_t *op; BSON_ASSERT (left); BSON_ASSERT ((opcode >= MONGOC_MATCHER_OPCODE_OR) && (opcode <= MONGOC_MATCHER_OPCODE_NOR)); op = (mongoc_matcher_op_t *)bson_malloc0 (sizeof *op); op->logical.base.opcode = opcode; op->logical.left = left; op->logical.right = right; return op; } /* *-------------------------------------------------------------------------- * * _mongoc_matcher_op_compare_new -- * * Create a new op for checking any of: * * {"abc": "def"} * {$gt: {...} * {$gte: {...} * {$lt: {...} * {$lte: {...} * {$ne: {...} * {$in: [...]} * {$nin: [...]} * * Returns: * A newly allocated mongoc_matcher_op_t that should be freed with * _mongoc_matcher_op_destroy(). * * Side effects: * None. * *-------------------------------------------------------------------------- */ mongoc_matcher_op_t * _mongoc_matcher_op_compare_new (mongoc_matcher_opcode_t opcode, /* IN */ const char *path, /* IN */ const bson_iter_t *iter) /* IN */ { mongoc_matcher_op_t *op; BSON_ASSERT (path); BSON_ASSERT (iter); op = (mongoc_matcher_op_t *)bson_malloc0 (sizeof *op); op->compare.base.opcode = opcode; op->compare.path = bson_strdup (path); memcpy (&op->compare.iter, iter, sizeof *iter); return op; } /* *-------------------------------------------------------------------------- * * _mongoc_matcher_op_not_new -- * * Create a new op for checking {$not: {...}} * * Returns: * A newly allocated mongoc_matcher_op_t that should be freed with * _mongoc_matcher_op_destroy(). * * Side effects: * None. * *-------------------------------------------------------------------------- */ mongoc_matcher_op_t * _mongoc_matcher_op_not_new (const char *path, /* IN */ mongoc_matcher_op_t *child) /* IN */ { mongoc_matcher_op_t *op; BSON_ASSERT (path); BSON_ASSERT (child); op = (mongoc_matcher_op_t *)bson_malloc0 (sizeof *op); op->not_.base.opcode = MONGOC_MATCHER_OPCODE_NOT; op->not_.path = bson_strdup (path); op->not_.child = child; return op; } /* *-------------------------------------------------------------------------- * * _mongoc_matcher_op_destroy -- * * Free a mongoc_matcher_op_t structure and all children structures. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void _mongoc_matcher_op_destroy (mongoc_matcher_op_t *op) /* IN */ { BSON_ASSERT (op); switch (op->base.opcode) { case MONGOC_MATCHER_OPCODE_EQ: case MONGOC_MATCHER_OPCODE_GT: case MONGOC_MATCHER_OPCODE_GTE: case MONGOC_MATCHER_OPCODE_IN: case MONGOC_MATCHER_OPCODE_LT: case MONGOC_MATCHER_OPCODE_LTE: case MONGOC_MATCHER_OPCODE_NE: case MONGOC_MATCHER_OPCODE_NIN: bson_free (op->compare.path); break; case MONGOC_MATCHER_OPCODE_OR: case MONGOC_MATCHER_OPCODE_AND: case MONGOC_MATCHER_OPCODE_NOR: if (op->logical.left) _mongoc_matcher_op_destroy (op->logical.left); if (op->logical.right) _mongoc_matcher_op_destroy (op->logical.right); break; case MONGOC_MATCHER_OPCODE_NOT: _mongoc_matcher_op_destroy (op->not_.child); bson_free (op->not_.path); break; case MONGOC_MATCHER_OPCODE_EXISTS: bson_free (op->exists.path); break; case MONGOC_MATCHER_OPCODE_TYPE: bson_free (op->type.path); break; default: break; } bson_free (op); } /* *-------------------------------------------------------------------------- * * _mongoc_matcher_op_exists_match -- * * Checks to see if @bson matches @exists requirements. The * {$exists: bool} query can be either true or fase so we must * handle false as "not exists". * * Returns: * true if the field exists and the spec expected it. * true if the field does not exist and the spec expected it to not * exist. * Otherwise, false. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static bool _mongoc_matcher_op_exists_match (mongoc_matcher_op_exists_t *exists, /* IN */ const bson_t *bson) /* IN */ { bson_iter_t iter; bson_iter_t desc; bool found; BSON_ASSERT (exists); BSON_ASSERT (bson); found = (bson_iter_init (&iter, bson) && bson_iter_find_descendant (&iter, exists->path, &desc)); return (found == exists->exists); } /* *-------------------------------------------------------------------------- * * _mongoc_matcher_op_type_match -- * * Checks if @bson matches the {$type: ...} op. * * Returns: * true if the requested field was found and the type matched * the requested type. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static bool _mongoc_matcher_op_type_match (mongoc_matcher_op_type_t *type, /* IN */ const bson_t *bson) /* IN */ { bson_iter_t iter; bson_iter_t desc; BSON_ASSERT (type); BSON_ASSERT (bson); if (bson_iter_init (&iter, bson) && bson_iter_find_descendant (&iter, type->path, &desc)) { return (bson_iter_type (&iter) == type->type); } return false; } /* *-------------------------------------------------------------------------- * * _mongoc_matcher_op_not_match -- * * Checks if the {$not: ...} expression matches by negating the * child expression. * * Returns: * true if the child expression returned false. * Otherwise false. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static bool _mongoc_matcher_op_not_match (mongoc_matcher_op_not_t *not_, /* IN */ const bson_t *bson) /* IN */ { BSON_ASSERT (not_); BSON_ASSERT (bson); return !_mongoc_matcher_op_match (not_->child, bson); } #define _TYPE_CODE(l, r) ((((int)(l)) << 8) | ((int)(r))) #define _NATIVE_COMPARE(op, t1, t2) \ (bson_iter##t2(iter) op bson_iter##t1(compare_iter)) #define _EQ_COMPARE(t1, t2) _NATIVE_COMPARE(==, t1, t2) #define _NE_COMPARE(t1, t2) _NATIVE_COMPARE(!=, t1, t2) #define _GT_COMPARE(t1, t2) _NATIVE_COMPARE(>, t1, t2) #define _GTE_COMPARE(t1, t2) _NATIVE_COMPARE(>=, t1, t2) #define _LT_COMPARE(t1, t2) _NATIVE_COMPARE(<, t1, t2) #define _LTE_COMPARE(t1, t2) _NATIVE_COMPARE(<=, t1, t2) /* *-------------------------------------------------------------------------- * * _mongoc_matcher_iter_eq_match -- * * Performs equality match for all types on either left or right * side of the equation. * * We try to default to what the compiler would do for comparing * things like integers. Therefore, we just have MACRO'tized * everything so that the compiler sees the native values. (Such * as (double == int64). * * The _TYPE_CODE() stuff allows us to shove the type of the left * and the right into a single integer and then do a jump table * with a switch/case for all our supported types. * * I imagine a bunch more of these will need to be added, so feel * free to submit patches. * * Returns: * true if the equality match succeeded. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static bool _mongoc_matcher_iter_eq_match (bson_iter_t *compare_iter, /* IN */ bson_iter_t *iter) /* IN */ { int code; BSON_ASSERT (compare_iter); BSON_ASSERT (iter); code = _TYPE_CODE (bson_iter_type (compare_iter), bson_iter_type (iter)); switch (code) { /* Double on Left Side */ case _TYPE_CODE(BSON_TYPE_DOUBLE, BSON_TYPE_DOUBLE): return _EQ_COMPARE (_double, _double); case _TYPE_CODE(BSON_TYPE_DOUBLE, BSON_TYPE_BOOL): return _EQ_COMPARE (_double, _bool); case _TYPE_CODE(BSON_TYPE_DOUBLE, BSON_TYPE_INT32): return _EQ_COMPARE (_double, _int32); case _TYPE_CODE(BSON_TYPE_DOUBLE, BSON_TYPE_INT64): return _EQ_COMPARE (_double, _int64); /* UTF8 on Left Side */ case _TYPE_CODE(BSON_TYPE_UTF8, BSON_TYPE_UTF8): { uint32_t llen; uint32_t rlen; const char *lstr; const char *rstr; lstr = bson_iter_utf8 (compare_iter, &llen); rstr = bson_iter_utf8 (iter, &rlen); return ((llen == rlen) && (0 == memcmp (lstr, rstr, llen))); } /* Int32 on Left Side */ case _TYPE_CODE(BSON_TYPE_INT32, BSON_TYPE_DOUBLE): return _EQ_COMPARE (_int32, _double); case _TYPE_CODE(BSON_TYPE_INT32, BSON_TYPE_BOOL): return _EQ_COMPARE (_int32, _bool); case _TYPE_CODE(BSON_TYPE_INT32, BSON_TYPE_INT32): return _EQ_COMPARE (_int32, _int32); case _TYPE_CODE(BSON_TYPE_INT32, BSON_TYPE_INT64): return _EQ_COMPARE (_int32, _int64); /* Int64 on Left Side */ case _TYPE_CODE(BSON_TYPE_INT64, BSON_TYPE_DOUBLE): return _EQ_COMPARE (_int64, _double); case _TYPE_CODE(BSON_TYPE_INT64, BSON_TYPE_BOOL): return _EQ_COMPARE (_int64, _bool); case _TYPE_CODE(BSON_TYPE_INT64, BSON_TYPE_INT32): return _EQ_COMPARE (_int64, _int32); case _TYPE_CODE(BSON_TYPE_INT64, BSON_TYPE_INT64): return _EQ_COMPARE (_int64, _int64); /* Null on Left Side */ case _TYPE_CODE(BSON_TYPE_NULL, BSON_TYPE_NULL): case _TYPE_CODE(BSON_TYPE_NULL, BSON_TYPE_UNDEFINED): return true; case _TYPE_CODE (BSON_TYPE_ARRAY, BSON_TYPE_ARRAY): { bson_iter_t left_array; bson_iter_t right_array; bson_iter_recurse (compare_iter, &left_array); bson_iter_recurse (iter, &right_array); while (true) { bool left_has_next = bson_iter_next (&left_array); bool right_has_next = bson_iter_next (&right_array); if (left_has_next != right_has_next) { /* different lengths */ return false; } if (!left_has_next) { /* finished */ return true; } if (!_mongoc_matcher_iter_eq_match (&left_array, &right_array)) { return false; } } } case _TYPE_CODE (BSON_TYPE_DOCUMENT, BSON_TYPE_DOCUMENT): { uint32_t llen; uint32_t rlen; const uint8_t *ldoc; const uint8_t *rdoc; bson_iter_document (compare_iter, &llen, &ldoc); bson_iter_document (iter, &rlen, &rdoc); return ((llen == rlen) && (0 == memcmp (ldoc, rdoc, llen))); } default: return false; } } /* *-------------------------------------------------------------------------- * * _mongoc_matcher_op_eq_match -- * * Performs equality match for all types on either left or right * side of the equation. * * Returns: * true if the equality match succeeded. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static bool _mongoc_matcher_op_eq_match (mongoc_matcher_op_compare_t *compare, /* IN */ bson_iter_t *iter) /* IN */ { BSON_ASSERT (compare); BSON_ASSERT (iter); return _mongoc_matcher_iter_eq_match (&compare->iter, iter); } /* *-------------------------------------------------------------------------- * * _mongoc_matcher_op_gt_match -- * * Perform {$gt: ...} match using @compare. * * In general, we try to default to what the compiler would do * for comparison between different types. * * Returns: * true if the document field was > the spec value. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static bool _mongoc_matcher_op_gt_match (mongoc_matcher_op_compare_t *compare, /* IN */ bson_iter_t *iter) /* IN */ { int code; bson_iter_t *compare_iter = &compare->iter; BSON_ASSERT (compare); BSON_ASSERT (iter); code = _TYPE_CODE (bson_iter_type (compare_iter), bson_iter_type (iter)); switch (code) { /* Double on Left Side */ case _TYPE_CODE(BSON_TYPE_DOUBLE, BSON_TYPE_DOUBLE): return _GT_COMPARE (_double, _double); case _TYPE_CODE(BSON_TYPE_DOUBLE, BSON_TYPE_BOOL): return _GT_COMPARE (_double, _bool); case _TYPE_CODE(BSON_TYPE_DOUBLE, BSON_TYPE_INT32): return _GT_COMPARE (_double, _int32); case _TYPE_CODE(BSON_TYPE_DOUBLE, BSON_TYPE_INT64): return _GT_COMPARE (_double, _int64); /* Int32 on Left Side */ case _TYPE_CODE(BSON_TYPE_INT32, BSON_TYPE_DOUBLE): return _GT_COMPARE (_int32, _double); case _TYPE_CODE(BSON_TYPE_INT32, BSON_TYPE_BOOL): return _GT_COMPARE (_int32, _bool); case _TYPE_CODE(BSON_TYPE_INT32, BSON_TYPE_INT32): return _GT_COMPARE (_int32, _int32); case _TYPE_CODE(BSON_TYPE_INT32, BSON_TYPE_INT64): return _GT_COMPARE (_int32, _int64); /* Int64 on Left Side */ case _TYPE_CODE(BSON_TYPE_INT64, BSON_TYPE_DOUBLE): return _GT_COMPARE (_int64, _double); case _TYPE_CODE(BSON_TYPE_INT64, BSON_TYPE_BOOL): return _GT_COMPARE (_int64, _bool); case _TYPE_CODE(BSON_TYPE_INT64, BSON_TYPE_INT32): return _GT_COMPARE (_int64, _int32); case _TYPE_CODE(BSON_TYPE_INT64, BSON_TYPE_INT64): return _GT_COMPARE (_int64, _int64); default: MONGOC_WARNING ("Implement for (Type(%d) > Type(%d))", bson_iter_type (compare_iter), bson_iter_type (iter)); break; } return false; } /* *-------------------------------------------------------------------------- * * _mongoc_matcher_op_gte_match -- * * Perform a match of {"path": {"$gte": value}}. * * Returns: * true if the the spec matches, otherwise false. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static bool _mongoc_matcher_op_gte_match (mongoc_matcher_op_compare_t *compare, /* IN */ bson_iter_t *iter) /* IN */ { bson_iter_t *compare_iter; int code; BSON_ASSERT (compare); BSON_ASSERT (iter); compare_iter = &compare->iter; code = _TYPE_CODE (bson_iter_type (compare_iter), bson_iter_type (iter)); switch (code) { /* Double on Left Side */ case _TYPE_CODE(BSON_TYPE_DOUBLE, BSON_TYPE_DOUBLE): return _GTE_COMPARE (_double, _double); case _TYPE_CODE(BSON_TYPE_DOUBLE, BSON_TYPE_BOOL): return _GTE_COMPARE (_double, _bool); case _TYPE_CODE(BSON_TYPE_DOUBLE, BSON_TYPE_INT32): return _GTE_COMPARE (_double, _int32); case _TYPE_CODE(BSON_TYPE_DOUBLE, BSON_TYPE_INT64): return _GTE_COMPARE (_double, _int64); /* Int32 on Left Side */ case _TYPE_CODE(BSON_TYPE_INT32, BSON_TYPE_DOUBLE): return _GTE_COMPARE (_int32, _double); case _TYPE_CODE(BSON_TYPE_INT32, BSON_TYPE_BOOL): return _GTE_COMPARE (_int32, _bool); case _TYPE_CODE(BSON_TYPE_INT32, BSON_TYPE_INT32): return _GTE_COMPARE (_int32, _int32); case _TYPE_CODE(BSON_TYPE_INT32, BSON_TYPE_INT64): return _GTE_COMPARE (_int32, _int64); /* Int64 on Left Side */ case _TYPE_CODE(BSON_TYPE_INT64, BSON_TYPE_DOUBLE): return _GTE_COMPARE (_int64, _double); case _TYPE_CODE(BSON_TYPE_INT64, BSON_TYPE_BOOL): return _GTE_COMPARE (_int64, _bool); case _TYPE_CODE(BSON_TYPE_INT64, BSON_TYPE_INT32): return _GTE_COMPARE (_int64, _int32); case _TYPE_CODE(BSON_TYPE_INT64, BSON_TYPE_INT64): return _GTE_COMPARE (_int64, _int64); default: MONGOC_WARNING ("Implement for (Type(%d) >= Type(%d))", bson_iter_type (compare_iter), bson_iter_type (iter)); break; } return false; } /* *-------------------------------------------------------------------------- * * _mongoc_matcher_op_in_match -- * * Checks the spec {"path": {"$in": [value1, value2, ...]}}. * * Returns: * true if the spec matched, otherwise false. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static bool _mongoc_matcher_op_in_match (mongoc_matcher_op_compare_t *compare, /* IN */ bson_iter_t *iter) /* IN */ { mongoc_matcher_op_compare_t op; op.base.opcode = MONGOC_MATCHER_OPCODE_EQ; op.path = compare->path; if (!BSON_ITER_HOLDS_ARRAY (&compare->iter) || !bson_iter_recurse (&compare->iter, &op.iter)) { return false; } while (bson_iter_next (&op.iter)) { if (_mongoc_matcher_op_eq_match (&op, iter)) { return true; } } return false; } /* *-------------------------------------------------------------------------- * * _mongoc_matcher_op_lt_match -- * * Perform a {"path": "$lt": {value}} match. * * Returns: * true if the spec matched, otherwise false. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static bool _mongoc_matcher_op_lt_match (mongoc_matcher_op_compare_t *compare, /* IN */ bson_iter_t *iter) /* IN */ { bson_iter_t *compare_iter; int code; BSON_ASSERT (compare); BSON_ASSERT (iter); compare_iter = &compare->iter; code = _TYPE_CODE (bson_iter_type (compare_iter), bson_iter_type (iter)); switch (code) { /* Double on Left Side */ case _TYPE_CODE(BSON_TYPE_DOUBLE, BSON_TYPE_DOUBLE): return _LT_COMPARE (_double, _double); case _TYPE_CODE(BSON_TYPE_DOUBLE, BSON_TYPE_BOOL): return _LT_COMPARE (_double, _bool); case _TYPE_CODE(BSON_TYPE_DOUBLE, BSON_TYPE_INT32): return _LT_COMPARE (_double, _int32); case _TYPE_CODE(BSON_TYPE_DOUBLE, BSON_TYPE_INT64): return _LT_COMPARE (_double, _int64); /* Int32 on Left Side */ case _TYPE_CODE(BSON_TYPE_INT32, BSON_TYPE_DOUBLE): return _LT_COMPARE (_int32, _double); case _TYPE_CODE(BSON_TYPE_INT32, BSON_TYPE_BOOL): return _LT_COMPARE (_int32, _bool); case _TYPE_CODE(BSON_TYPE_INT32, BSON_TYPE_INT32): return _LT_COMPARE (_int32, _int32); case _TYPE_CODE(BSON_TYPE_INT32, BSON_TYPE_INT64): return _LT_COMPARE (_int32, _int64); /* Int64 on Left Side */ case _TYPE_CODE(BSON_TYPE_INT64, BSON_TYPE_DOUBLE): return _LT_COMPARE (_int64, _double); case _TYPE_CODE(BSON_TYPE_INT64, BSON_TYPE_BOOL): return _LT_COMPARE (_int64, _bool); case _TYPE_CODE(BSON_TYPE_INT64, BSON_TYPE_INT32): return _LT_COMPARE (_int64, _int32); case _TYPE_CODE(BSON_TYPE_INT64, BSON_TYPE_INT64): return _LT_COMPARE (_int64, _int64); default: MONGOC_WARNING ("Implement for (Type(%d) < Type(%d))", bson_iter_type (compare_iter), bson_iter_type (iter)); break; } return false; } /* *-------------------------------------------------------------------------- * * _mongoc_matcher_op_lte_match -- * * Perform a {"$path": {"$lte": value}} match. * * Returns: * true if the spec matched, otherwise false. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static bool _mongoc_matcher_op_lte_match (mongoc_matcher_op_compare_t *compare, /* IN */ bson_iter_t *iter) /* IN */ { bson_iter_t *compare_iter; int code; BSON_ASSERT (compare); BSON_ASSERT (iter); compare_iter = &compare->iter; code = _TYPE_CODE (bson_iter_type (compare_iter), bson_iter_type (iter)); switch (code) { /* Double on Left Side */ case _TYPE_CODE(BSON_TYPE_DOUBLE, BSON_TYPE_DOUBLE): return _LTE_COMPARE (_double, _double); case _TYPE_CODE(BSON_TYPE_DOUBLE, BSON_TYPE_BOOL): return _LTE_COMPARE (_double, _bool); case _TYPE_CODE(BSON_TYPE_DOUBLE, BSON_TYPE_INT32): return _LTE_COMPARE (_double, _int32); case _TYPE_CODE(BSON_TYPE_DOUBLE, BSON_TYPE_INT64): return _LTE_COMPARE (_double, _int64); /* Int32 on Left Side */ case _TYPE_CODE(BSON_TYPE_INT32, BSON_TYPE_DOUBLE): return _LTE_COMPARE (_int32, _double); case _TYPE_CODE(BSON_TYPE_INT32, BSON_TYPE_BOOL): return _LTE_COMPARE (_int32, _bool); case _TYPE_CODE(BSON_TYPE_INT32, BSON_TYPE_INT32): return _LTE_COMPARE (_int32, _int32); case _TYPE_CODE(BSON_TYPE_INT32, BSON_TYPE_INT64): return _LTE_COMPARE (_int32, _int64); /* Int64 on Left Side */ case _TYPE_CODE(BSON_TYPE_INT64, BSON_TYPE_DOUBLE): return _LTE_COMPARE (_int64, _double); case _TYPE_CODE(BSON_TYPE_INT64, BSON_TYPE_BOOL): return _LTE_COMPARE (_int64, _bool); case _TYPE_CODE(BSON_TYPE_INT64, BSON_TYPE_INT32): return _LTE_COMPARE (_int64, _int32); case _TYPE_CODE(BSON_TYPE_INT64, BSON_TYPE_INT64): return _LTE_COMPARE (_int64, _int64); default: MONGOC_WARNING ("Implement for (Type(%d) <= Type(%d))", bson_iter_type (compare_iter), bson_iter_type (iter)); break; } return false; } /* *-------------------------------------------------------------------------- * * _mongoc_matcher_op_ne_match -- * * Perform a {"path": {"$ne": value}} match. * * Returns: * true if the field "path" was not found or the value is not-equal * to value. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static bool _mongoc_matcher_op_ne_match (mongoc_matcher_op_compare_t *compare, /* IN */ bson_iter_t *iter) /* IN */ { return !_mongoc_matcher_op_eq_match (compare, iter); } /* *-------------------------------------------------------------------------- * * _mongoc_matcher_op_nin_match -- * * Perform a {"path": {"$nin": value}} match. * * Returns: * true if value was not found in the array at "path". * * Side effects: * None. * *-------------------------------------------------------------------------- */ static bool _mongoc_matcher_op_nin_match (mongoc_matcher_op_compare_t *compare, /* IN */ bson_iter_t *iter) /* IN */ { return !_mongoc_matcher_op_in_match (compare, iter); } /* *-------------------------------------------------------------------------- * * _mongoc_matcher_op_compare_match -- * * Dispatch function for mongoc_matcher_op_compare_t operations * to perform a match. * * Returns: * Opcode dependent. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static bool _mongoc_matcher_op_compare_match (mongoc_matcher_op_compare_t *compare, /* IN */ const bson_t *bson) /* IN */ { bson_iter_t tmp; bson_iter_t iter; BSON_ASSERT (compare); BSON_ASSERT (bson); if (strchr (compare->path, '.')) { if (!bson_iter_init (&tmp, bson) || !bson_iter_find_descendant (&tmp, compare->path, &iter)) { return false; } } else if (!bson_iter_init_find (&iter, bson, compare->path)) { return false; } switch ((int)compare->base.opcode) { case MONGOC_MATCHER_OPCODE_EQ: return _mongoc_matcher_op_eq_match (compare, &iter); case MONGOC_MATCHER_OPCODE_GT: return _mongoc_matcher_op_gt_match (compare, &iter); case MONGOC_MATCHER_OPCODE_GTE: return _mongoc_matcher_op_gte_match (compare, &iter); case MONGOC_MATCHER_OPCODE_IN: return _mongoc_matcher_op_in_match (compare, &iter); case MONGOC_MATCHER_OPCODE_LT: return _mongoc_matcher_op_lt_match (compare, &iter); case MONGOC_MATCHER_OPCODE_LTE: return _mongoc_matcher_op_lte_match (compare, &iter); case MONGOC_MATCHER_OPCODE_NE: return _mongoc_matcher_op_ne_match (compare, &iter); case MONGOC_MATCHER_OPCODE_NIN: return _mongoc_matcher_op_nin_match (compare, &iter); default: BSON_ASSERT (false); break; } return false; } /* *-------------------------------------------------------------------------- * * _mongoc_matcher_op_logical_match -- * * Dispatch function for mongoc_matcher_op_logical_t operations * to perform a match. * * Returns: * Opcode specific. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static bool _mongoc_matcher_op_logical_match (mongoc_matcher_op_logical_t *logical, /* IN */ const bson_t *bson) /* IN */ { BSON_ASSERT (logical); BSON_ASSERT (bson); switch ((int)logical->base.opcode) { case MONGOC_MATCHER_OPCODE_OR: return (_mongoc_matcher_op_match (logical->left, bson) || _mongoc_matcher_op_match (logical->right, bson)); case MONGOC_MATCHER_OPCODE_AND: return (_mongoc_matcher_op_match (logical->left, bson) && _mongoc_matcher_op_match (logical->right, bson)); case MONGOC_MATCHER_OPCODE_NOR: return !(_mongoc_matcher_op_match (logical->left, bson) || _mongoc_matcher_op_match (logical->right, bson)); default: BSON_ASSERT (false); break; } return false; } /* *-------------------------------------------------------------------------- * * _mongoc_matcher_op_match -- * * Dispatch function for all operation types to perform a match. * * Returns: * Opcode specific. * * Side effects: * None. * *-------------------------------------------------------------------------- */ bool _mongoc_matcher_op_match (mongoc_matcher_op_t *op, /* IN */ const bson_t *bson) /* IN */ { BSON_ASSERT (op); BSON_ASSERT (bson); switch (op->base.opcode) { case MONGOC_MATCHER_OPCODE_EQ: case MONGOC_MATCHER_OPCODE_GT: case MONGOC_MATCHER_OPCODE_GTE: case MONGOC_MATCHER_OPCODE_IN: case MONGOC_MATCHER_OPCODE_LT: case MONGOC_MATCHER_OPCODE_LTE: case MONGOC_MATCHER_OPCODE_NE: case MONGOC_MATCHER_OPCODE_NIN: return _mongoc_matcher_op_compare_match (&op->compare, bson); case MONGOC_MATCHER_OPCODE_OR: case MONGOC_MATCHER_OPCODE_AND: case MONGOC_MATCHER_OPCODE_NOR: return _mongoc_matcher_op_logical_match (&op->logical, bson); case MONGOC_MATCHER_OPCODE_NOT: return _mongoc_matcher_op_not_match (&op->not_, bson); case MONGOC_MATCHER_OPCODE_EXISTS: return _mongoc_matcher_op_exists_match (&op->exists, bson); case MONGOC_MATCHER_OPCODE_TYPE: return _mongoc_matcher_op_type_match (&op->type, bson); default: break; } return false; } /* *-------------------------------------------------------------------------- * * _mongoc_matcher_op_to_bson -- * * Convert the optree specified by @op to a bson document similar * to what the query would have been. This is not perfectly the * same, and so should not be used as such. * * Returns: * None. * * Side effects: * @bson is appended to, and therefore must be initialized before * calling this function. * *-------------------------------------------------------------------------- */ void _mongoc_matcher_op_to_bson (mongoc_matcher_op_t *op, /* IN */ bson_t *bson) /* IN */ { const char *str; bson_t child; bson_t child2; BSON_ASSERT (op); BSON_ASSERT (bson); switch (op->base.opcode) { case MONGOC_MATCHER_OPCODE_EQ: _ignore_value(bson_append_iter (bson, op->compare.path, -1, &op->compare.iter)); break; case MONGOC_MATCHER_OPCODE_GT: case MONGOC_MATCHER_OPCODE_GTE: case MONGOC_MATCHER_OPCODE_IN: case MONGOC_MATCHER_OPCODE_LT: case MONGOC_MATCHER_OPCODE_LTE: case MONGOC_MATCHER_OPCODE_NE: case MONGOC_MATCHER_OPCODE_NIN: switch ((int)op->base.opcode) { case MONGOC_MATCHER_OPCODE_GT: str = "$gt"; break; case MONGOC_MATCHER_OPCODE_GTE: str = "$gte"; break; case MONGOC_MATCHER_OPCODE_IN: str = "$in"; break; case MONGOC_MATCHER_OPCODE_LT: str = "$lt"; break; case MONGOC_MATCHER_OPCODE_LTE: str = "$lte"; break; case MONGOC_MATCHER_OPCODE_NE: str = "$ne"; break; case MONGOC_MATCHER_OPCODE_NIN: str = "$nin"; break; default: str = "???"; break; } if (bson_append_document_begin (bson, op->compare.path, -1, &child)) { _ignore_value (bson_append_iter (&child, str, -1, &op->compare.iter)); bson_append_document_end (bson, &child); } break; case MONGOC_MATCHER_OPCODE_OR: case MONGOC_MATCHER_OPCODE_AND: case MONGOC_MATCHER_OPCODE_NOR: if (op->base.opcode == MONGOC_MATCHER_OPCODE_OR) { str = "$or"; } else if (op->base.opcode == MONGOC_MATCHER_OPCODE_AND) { str = "$and"; } else if (op->base.opcode == MONGOC_MATCHER_OPCODE_NOR) { str = "$nor"; } else { BSON_ASSERT (false); str = NULL; } bson_append_array_begin (bson, str, -1, &child); bson_append_document_begin (&child, "0", 1, &child2); _mongoc_matcher_op_to_bson (op->logical.left, &child2); bson_append_document_end (&child, &child2); if (op->logical.right) { bson_append_document_begin (&child, "1", 1, &child2); _mongoc_matcher_op_to_bson (op->logical.right, &child2); bson_append_document_end (&child, &child2); } bson_append_array_end (bson, &child); break; case MONGOC_MATCHER_OPCODE_NOT: bson_append_document_begin (bson, op->not_.path, -1, &child); bson_append_document_begin (&child, "$not", 4, &child2); _mongoc_matcher_op_to_bson (op->not_.child, &child2); bson_append_document_end (&child, &child2); bson_append_document_end (bson, &child); break; case MONGOC_MATCHER_OPCODE_EXISTS: BSON_APPEND_BOOL (bson, "$exists", op->exists.exists); break; case MONGOC_MATCHER_OPCODE_TYPE: BSON_APPEND_INT32 (bson, "$type", (int)op->type.type); break; default: BSON_ASSERT (false); break; } } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-matcher-private.h0000664000175000017500000000177412673034026024354 0ustar jmikolajmikola/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_MATCHER_PRIVATE_H #define MONGOC_MATCHER_PRIVATE_H #if !defined (MONGOC_I_AM_A_DRIVER) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #include #include "mongoc-matcher-op-private.h" BSON_BEGIN_DECLS struct _mongoc_matcher_t { bson_t query; mongoc_matcher_op_t *optree; }; BSON_END_DECLS #endif /* MONGOC_MATCHER_PRIVATE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-matcher.c0000664000175000017500000002744312673034026022700 0ustar jmikolajmikola/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include "mongoc-error.h" #include "mongoc-matcher.h" #include "mongoc-matcher-private.h" #include "mongoc-matcher-op-private.h" static mongoc_matcher_op_t * _mongoc_matcher_parse_logical (mongoc_matcher_opcode_t opcode, bson_iter_t *iter, bool is_root, bson_error_t *error); /* *-------------------------------------------------------------------------- * * _mongoc_matcher_parse_compare -- * * Parse a compare spec such as $gt or $in. * * See the following link for more information. * * http://docs.mongodb.org/manual/reference/operator/query/ * * Returns: * A newly allocated mongoc_matcher_op_t if successful; otherwise * NULL and @error is set. * * Side effects: * @error may be set. * *-------------------------------------------------------------------------- */ static mongoc_matcher_op_t * _mongoc_matcher_parse_compare (bson_iter_t *iter, /* IN */ const char *path, /* IN */ bson_error_t *error) /* OUT */ { const char * key; mongoc_matcher_op_t * op = NULL, * op_child; bson_iter_t child; BSON_ASSERT (iter); BSON_ASSERT (path); if (bson_iter_type (iter) == BSON_TYPE_DOCUMENT) { if (!bson_iter_recurse (iter, &child) || !bson_iter_next (&child)) { bson_set_error (error, MONGOC_ERROR_MATCHER, MONGOC_ERROR_MATCHER_INVALID, "Document contains no operations."); return NULL; } key = bson_iter_key (&child); if (key[0] != '$') { op = _mongoc_matcher_op_compare_new (MONGOC_MATCHER_OPCODE_EQ, path, iter); } else if (strcmp(key, "$not") == 0) { if (!(op_child = _mongoc_matcher_parse_compare (&child, path, error))) { return NULL; } op = _mongoc_matcher_op_not_new (path, op_child); } else if (strcmp(key, "$gt") == 0) { op = _mongoc_matcher_op_compare_new (MONGOC_MATCHER_OPCODE_GT, path, &child); } else if (strcmp(key, "$gte") == 0) { op = _mongoc_matcher_op_compare_new (MONGOC_MATCHER_OPCODE_GTE, path, &child); } else if (strcmp(key, "$in") == 0) { op = _mongoc_matcher_op_compare_new (MONGOC_MATCHER_OPCODE_IN, path, &child); } else if (strcmp(key, "$lt") == 0) { op = _mongoc_matcher_op_compare_new (MONGOC_MATCHER_OPCODE_LT, path, &child); } else if (strcmp(key, "$lte") == 0) { op = _mongoc_matcher_op_compare_new (MONGOC_MATCHER_OPCODE_LTE, path, &child); } else if (strcmp(key, "$ne") == 0) { op = _mongoc_matcher_op_compare_new (MONGOC_MATCHER_OPCODE_NE, path, &child); } else if (strcmp(key, "$nin") == 0) { op = _mongoc_matcher_op_compare_new (MONGOC_MATCHER_OPCODE_NIN, path, &child); } else if (strcmp(key, "$exists") == 0) { op = _mongoc_matcher_op_exists_new (path, bson_iter_bool (&child)); } else if (strcmp(key, "$type") == 0) { op = _mongoc_matcher_op_type_new (path, bson_iter_type (&child)); } else { bson_set_error (error, MONGOC_ERROR_MATCHER, MONGOC_ERROR_MATCHER_INVALID, "Invalid operator \"%s\"", key); return NULL; } } else { op = _mongoc_matcher_op_compare_new (MONGOC_MATCHER_OPCODE_EQ, path, iter); } BSON_ASSERT (op); return op; } /* *-------------------------------------------------------------------------- * * _mongoc_matcher_parse -- * * Parse a query spec observed by the current key of @iter. * * Returns: * A newly allocated mongoc_matcher_op_t if successful; otherwise * NULL an @error is set. * * Side effects: * @error may be set. * *-------------------------------------------------------------------------- */ static mongoc_matcher_op_t * _mongoc_matcher_parse (bson_iter_t *iter, /* IN */ bson_error_t *error) /* OUT */ { bson_iter_t child; const char *key; BSON_ASSERT (iter); key = bson_iter_key (iter); if (*key != '$') { return _mongoc_matcher_parse_compare (iter, key, error); } else { BSON_ASSERT (bson_iter_type(iter) == BSON_TYPE_ARRAY); if (!bson_iter_recurse (iter, &child)) { bson_set_error (error, MONGOC_ERROR_MATCHER, MONGOC_ERROR_MATCHER_INVALID, "Invalid value for operator \"%s\"", key); return NULL; } if (strcmp (key, "$or") == 0) { return _mongoc_matcher_parse_logical (MONGOC_MATCHER_OPCODE_OR, &child, false, error); } else if (strcmp(key, "$and") == 0) { return _mongoc_matcher_parse_logical (MONGOC_MATCHER_OPCODE_AND, &child, false, error); } else if (strcmp(key, "$nor") == 0) { return _mongoc_matcher_parse_logical (MONGOC_MATCHER_OPCODE_NOR, &child, false, error); } } bson_set_error (error, MONGOC_ERROR_MATCHER, MONGOC_ERROR_MATCHER_INVALID, "Invalid operator \"%s\"", key); return NULL; } /* *-------------------------------------------------------------------------- * * _mongoc_matcher_parse_logical -- * * Parse a query spec containing a logical operator such as * $or, $and, $not, and $nor. * * See the following link for more information. * * http://docs.mongodb.org/manual/reference/operator/query/ * * Returns: * A newly allocated mongoc_matcher_op_t if successful; otherwise * NULL and @error is set. * * Side effects: * @error may be set. * *-------------------------------------------------------------------------- */ static mongoc_matcher_op_t * _mongoc_matcher_parse_logical (mongoc_matcher_opcode_t opcode, /* IN */ bson_iter_t *iter, /* IN */ bool is_root, /* IN */ bson_error_t *error) /* OUT */ { mongoc_matcher_op_t *left; mongoc_matcher_op_t *right; mongoc_matcher_op_t *more; mongoc_matcher_op_t *more_wrap; bson_iter_t child; BSON_ASSERT (opcode); BSON_ASSERT (iter); BSON_ASSERT (iter); if (!bson_iter_next (iter)) { bson_set_error (error, MONGOC_ERROR_MATCHER, MONGOC_ERROR_MATCHER_INVALID, "Invalid logical operator."); return NULL; } if (is_root) { if (!(left = _mongoc_matcher_parse (iter, error))) { return NULL; } } else { if (!BSON_ITER_HOLDS_DOCUMENT (iter)) { bson_set_error (error, MONGOC_ERROR_MATCHER, MONGOC_ERROR_MATCHER_INVALID, "Expected document in value."); return NULL; } bson_iter_recurse (iter, &child); bson_iter_next (&child); if (!(left = _mongoc_matcher_parse (&child, error))) { return NULL; } } if (!bson_iter_next (iter)) { return left; } if (is_root) { if (!(right = _mongoc_matcher_parse (iter, error))) { return NULL; } } else { if (!BSON_ITER_HOLDS_DOCUMENT (iter)) { bson_set_error (error, MONGOC_ERROR_MATCHER, MONGOC_ERROR_MATCHER_INVALID, "Expected document in value."); return NULL; } bson_iter_recurse (iter, &child); bson_iter_next (&child); if (!(right = _mongoc_matcher_parse (&child, error))) { return NULL; } } more = _mongoc_matcher_parse_logical (opcode, iter, is_root, error); if (more) { more_wrap = _mongoc_matcher_op_logical_new (opcode, right, more); return _mongoc_matcher_op_logical_new (opcode, left, more_wrap); } return _mongoc_matcher_op_logical_new (opcode, left, right); } /* *-------------------------------------------------------------------------- * * mongoc_matcher_new -- * * Create a new mongoc_matcher_t using the query specification * provided in @query. * * This will build an operation tree that can be applied to arbitrary * bson documents using mongoc_matcher_match(). * * Returns: * A newly allocated mongoc_matcher_t if successful; otherwise NULL * and @error is set. * * The mongoc_matcher_t should be freed with * mongoc_matcher_destroy(). * * Side effects: * @error may be set. * *-------------------------------------------------------------------------- */ mongoc_matcher_t * mongoc_matcher_new (const bson_t *query, /* IN */ bson_error_t *error) /* OUT */ { mongoc_matcher_op_t *op; mongoc_matcher_t *matcher; bson_iter_t iter; BSON_ASSERT (query); matcher = (mongoc_matcher_t *)bson_malloc0 (sizeof *matcher); bson_copy_to (query, &matcher->query); if (!bson_iter_init (&iter, &matcher->query)) { goto failure; } if (!(op = _mongoc_matcher_parse_logical (MONGOC_MATCHER_OPCODE_AND, &iter, true, error))) { goto failure; } matcher->optree = op; return matcher; failure: bson_destroy (&matcher->query); bson_free (matcher); return NULL; } /* *-------------------------------------------------------------------------- * * mongoc_matcher_match -- * * Checks to see if @bson matches the query specified when creating * @matcher. * * Returns: * TRUE if @bson matched the query, otherwise FALSE. * * Side effects: * None. * *-------------------------------------------------------------------------- */ bool mongoc_matcher_match (const mongoc_matcher_t *matcher, /* IN */ const bson_t *document) /* IN */ { BSON_ASSERT (matcher); BSON_ASSERT (matcher->optree); BSON_ASSERT (document); return _mongoc_matcher_op_match (matcher->optree, document); } /* *-------------------------------------------------------------------------- * * mongoc_matcher_destroy -- * * Release all resources associated with @matcher. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void mongoc_matcher_destroy (mongoc_matcher_t *matcher) /* IN */ { BSON_ASSERT (matcher); _mongoc_matcher_op_destroy (matcher->optree); bson_destroy (&matcher->query); bson_free (matcher); } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-matcher.h0000664000175000017500000000251612673034026022677 0ustar jmikolajmikola/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_MATCHER_H #define MONGOC_MATCHER_H #if !defined (MONGOC_INSIDE) && !defined (MONGOC_COMPILATION) # error "Only can be included directly." #endif #include BSON_BEGIN_DECLS typedef struct _mongoc_matcher_t mongoc_matcher_t; mongoc_matcher_t *mongoc_matcher_new (const bson_t *query, bson_error_t *error) BSON_GNUC_DEPRECATED; bool mongoc_matcher_match (const mongoc_matcher_t *matcher, const bson_t *document) BSON_GNUC_DEPRECATED; void mongoc_matcher_destroy (mongoc_matcher_t *matcher) BSON_GNUC_DEPRECATED; BSON_END_DECLS #endif /* MONGOC_MATCHER_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-memcmp-private.h0000664000175000017500000000224312673034026024177 0ustar jmikolajmikola/* * Copyright 2015 MongoDB Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_MEMCMP_PRIVATE_H #define MONGOC_MEMCMP_PRIVATE_H #if !defined (MONGOC_I_AM_A_DRIVER) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #include #include "mongoc-config.h" /* WARNING: mongoc_memcmp() must be used to verify if two secret keys * are equal, in constant time. * It returns 0 if the keys are equal, and -1 if they differ. * This function is not designed for lexicographical comparisons. */ int mongoc_memcmp(const void * const b1_, const void * const b2_, size_t len); #endif /* MONGOC_MEMCMP_PRIVATE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-memcmp.c0000664000175000017500000000360412673034026022524 0ustar jmikolajmikola/* * Copyright (c) 2013-2015 * Frank Denis * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include "mongoc-memcmp-private.h" #ifdef MONGOC_HAVE_WEAK_SYMBOLS __attribute__((weak)) void _mongoc_dummy_symbol_to_prevent_memcmp_lto(const unsigned char *b1, const unsigned char *b2, const size_t len) { (void) b1; (void) b2; (void) len; } #endif /* See: http://doc.libsodium.org/helpers/index.html#constant-time-comparison */ int mongoc_memcmp(const void * const b1_, const void * const b2_, size_t len) { #ifdef MONGOC_HAVE_WEAK_SYMBOLS const unsigned char *b1 = (const unsigned char *) b1_; const unsigned char *b2 = (const unsigned char *) b2_; #else const volatile unsigned char *b1 = (const volatile unsigned char *) b1_; const volatile unsigned char *b2 = (const volatile unsigned char *) b2_; #endif size_t i; unsigned char d = (unsigned char) 0U; #if MONGOC_HAVE_WEAK_SYMBOLS _mongoc_dummy_symbol_to_prevent_memcmp_lto(b1, b2, len); #endif for (i = 0U; i < len; i++) { d |= b1[i] ^ b2[i]; } return (int) ((1 & ((d - 1) >> 8)) - 1); } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-opcode-private.h0000664000175000017500000000142212673034026024170 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_OPCODE_PRIVATE_H #define MONGOC_OPCODE_PRIVATE_H #include "mongoc-opcode.h" bool _mongoc_opcode_needs_primary(mongoc_opcode_t opcode); #endif /* MONGOC_OPCODE_PRIVATE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-opcode.c0000664000175000017500000000332512673034026022517 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "mongoc-opcode-private.h" /* *-------------------------------------------------------------------------- * * _mongoc_opcode_needs_primary -- * * Returns true if this operation needs to run on a primary, * false if it does not. * * Returns: * true, false * * Side effects: * None * *-------------------------------------------------------------------------- */ bool _mongoc_opcode_needs_primary (mongoc_opcode_t opcode) { bool needs_primary = false; switch(opcode) { case MONGOC_OPCODE_KILL_CURSORS: case MONGOC_OPCODE_GET_MORE: case MONGOC_OPCODE_MSG: case MONGOC_OPCODE_REPLY: needs_primary = false; break; case MONGOC_OPCODE_QUERY: /* In some cases, queries may be run against secondaries. However, more information is needed to make that decision. Callers with access to read preferences and query flags may route queries to a secondary when appropriate */ case MONGOC_OPCODE_DELETE: case MONGOC_OPCODE_INSERT: case MONGOC_OPCODE_UPDATE: default: needs_primary = true; break; } return needs_primary; } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-opcode.h0000664000175000017500000000225512673034026022525 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_OPCODE_H #define MONGOC_OPCODE_H #if !defined (MONGOC_INSIDE) && !defined (MONGOC_COMPILATION) # error "Only can be included directly." #endif #include BSON_BEGIN_DECLS typedef enum { MONGOC_OPCODE_REPLY = 1, MONGOC_OPCODE_MSG = 1000, MONGOC_OPCODE_UPDATE = 2001, MONGOC_OPCODE_INSERT = 2002, MONGOC_OPCODE_QUERY = 2004, MONGOC_OPCODE_GET_MORE = 2005, MONGOC_OPCODE_DELETE = 2006, MONGOC_OPCODE_KILL_CURSORS = 2007, } mongoc_opcode_t; BSON_END_DECLS #endif /* MONGOC_OPCODE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-queue-private.h0000664000175000017500000000326412673034026024051 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_QUEUE_PRIVATE_H #define MONGOC_QUEUE_PRIVATE_H #if !defined (MONGOC_I_AM_A_DRIVER) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #include #include "mongoc-list-private.h" BSON_BEGIN_DECLS #define MONGOC_QUEUE_INITIALIZER {NULL,NULL} typedef struct _mongoc_queue_t mongoc_queue_t; typedef struct _mongoc_queue_item_t mongoc_queue_item_t; struct _mongoc_queue_t { mongoc_queue_item_t *head; mongoc_queue_item_t *tail; }; struct _mongoc_queue_item_t { mongoc_queue_item_t *next; void *data; }; void _mongoc_queue_init (mongoc_queue_t *queue); void *_mongoc_queue_pop_head (mongoc_queue_t *queue); void _mongoc_queue_push_head (mongoc_queue_t *queue, void *data); void _mongoc_queue_push_tail (mongoc_queue_t *queue, void *data); uint32_t _mongoc_queue_get_length (const mongoc_queue_t *queue); BSON_END_DECLS #endif /* MONGOC_QUEUE_PRIVATE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-queue.c0000664000175000017500000000407512673034026022375 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include "mongoc-queue-private.h" void _mongoc_queue_init (mongoc_queue_t *queue) { BSON_ASSERT (queue); memset (queue, 0, sizeof *queue); } void _mongoc_queue_push_head (mongoc_queue_t *queue, void *data) { mongoc_queue_item_t *item; BSON_ASSERT (queue); BSON_ASSERT (data); item = (mongoc_queue_item_t *)bson_malloc0(sizeof *item); item->next = queue->head; item->data = data; queue->head = item; if (!queue->tail) { queue->tail = item; } } void _mongoc_queue_push_tail (mongoc_queue_t *queue, void *data) { mongoc_queue_item_t *item; BSON_ASSERT (queue); BSON_ASSERT (data); item = (mongoc_queue_item_t *)bson_malloc0(sizeof *item); item->data = data; if (queue->tail) { queue->tail->next = item; } else { queue->head = item; } queue->tail = item; } void * _mongoc_queue_pop_head (mongoc_queue_t *queue) { mongoc_queue_item_t *item; void *data = NULL; BSON_ASSERT (queue); if ((item = queue->head)) { if (!item->next) { queue->tail = NULL; } queue->head = item->next; data = item->data; bson_free(item); } return data; } uint32_t _mongoc_queue_get_length (const mongoc_queue_t *queue) { mongoc_queue_item_t *item; uint32_t count = 0; BSON_ASSERT (queue); for (item = queue->head; item; item = item->next) { count++; } return count; } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-rand-private.h0000664000175000017500000000172612673034026023652 0ustar jmikolajmikola/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if !defined (MONGOC_I_AM_A_DRIVER) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #ifndef MONGOC_RAND_PRIVATE_H #define MONGOC_RAND_PRIVATE_H #include BSON_BEGIN_DECLS int _mongoc_rand_bytes(uint8_t * buf, int num); int _mongoc_pseudo_rand_bytes(uint8_t * buf, int num); BSON_END_DECLS #endif /* MONGOC_RAND_PRIVATE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-rand.c0000664000175000017500000000224312673034026022170 0ustar jmikolajmikola/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "mongoc-config.h" #ifdef MONGOC_ENABLE_SSL #include "mongoc-rand.h" #include "mongoc-rand-private.h" #include "mongoc.h" #include int _mongoc_rand_bytes(uint8_t * buf, int num) { return RAND_bytes(buf, num); } int _mongoc_pseudo_rand_bytes(uint8_t * buf, int num) { return RAND_pseudo_bytes(buf, num); } void mongoc_rand_seed(const void* buf, int num) { RAND_seed(buf, num); } void mongoc_rand_add(const void* buf, int num, double entropy) { RAND_add(buf, num, entropy); } int mongoc_rand_status(void) { return RAND_status(); } #endif mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-rand.h0000664000175000017500000000173712673034026022204 0ustar jmikolajmikola/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if !defined (MONGOC_INSIDE) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #ifndef MONGOC_RAND_H #define MONGOC_RAND_H #include BSON_BEGIN_DECLS void mongoc_rand_seed(const void* buf, int num); void mongoc_rand_add(const void* buf, int num, double entropy); int mongoc_rand_status(void); BSON_END_DECLS #endif /* MONGOC_RAND_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-read-concern-private.h0000664000175000017500000000213712673034026025263 0ustar jmikolajmikola/* * Copyright 2015 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_READ_CONCERN_PRIVATE_H #define MONGOC_READ_CONCERN_PRIVATE_H #if !defined (MONGOC_I_AM_A_DRIVER) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #include #include "mongoc-read-concern.h" BSON_BEGIN_DECLS struct _mongoc_read_concern_t { char *level; bool frozen; bson_t compiled; }; const bson_t *_mongoc_read_concern_get_bson (mongoc_read_concern_t *read_concern); BSON_END_DECLS #endif /* MONGOC_READ_CONCERN_PRIVATE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-read-concern.c0000664000175000017500000001016512673034026023606 0ustar jmikolajmikola/* * Copyright 2015 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "mongoc-log.h" #include "mongoc-read-concern.h" #include "mongoc-read-concern-private.h" static void _mongoc_read_concern_freeze (mongoc_read_concern_t *read_concern); /** * mongoc_read_concern_new: * * Create a new mongoc_read_concern_t. * * Returns: A newly allocated mongoc_read_concern_t. This should be freed * with mongoc_read_concern_destroy(). */ mongoc_read_concern_t * mongoc_read_concern_new (void) { mongoc_read_concern_t *read_concern; read_concern = (mongoc_read_concern_t *)bson_malloc0 (sizeof *read_concern); return read_concern; } mongoc_read_concern_t * mongoc_read_concern_copy (const mongoc_read_concern_t *read_concern) { mongoc_read_concern_t *ret = NULL; if (read_concern) { ret = mongoc_read_concern_new (); ret->level = bson_strdup (read_concern->level); } return ret; } /** * mongoc_read_concern_destroy: * @read_concern: A mongoc_read_concern_t. * * Releases a mongoc_read_concern_t and all associated memory. */ void mongoc_read_concern_destroy (mongoc_read_concern_t *read_concern) { if (read_concern) { if (read_concern->compiled.len) { bson_destroy (&read_concern->compiled); } bson_free (read_concern->level); bson_free (read_concern); } } const char * mongoc_read_concern_get_level (const mongoc_read_concern_t *read_concern) { BSON_ASSERT (read_concern); return read_concern->level; } /** * mongoc_read_concern_set_level: * @read_concern: A mongoc_read_concern_t. * @level: The read concern level * * Sets the read concern level. Any string is supported for future compatability * but MongoDB 3.2 only accepts "local" and "majority", aka: * - MONGOC_READ_CONCERN_LEVEL_LOCAL * - MONGOC_READ_CONCERN_LEVEL_MAJORITY * * If the @read_concern has already been frozen, calling this function will not * alter the read concern level. * * See the MongoDB docs for more information on readConcernLevel */ bool mongoc_read_concern_set_level (mongoc_read_concern_t *read_concern, const char *level) { BSON_ASSERT (read_concern); if (read_concern->frozen) { return false; } bson_free (read_concern->level); read_concern->level = bson_strdup (level); return true; } /** * mongoc_read_concern_get_bson: * @read_concern: A mongoc_read_concern_t. * * This is an internal function. * * Freeze the read concern if necessary and retrieve the encoded bson_t * representing the read concern. * * You may not modify the read concern further after calling this function. * * Returns: A bson_t that should not be modified or freed as it is owned by * the mongoc_read_concern_t instance. */ const bson_t * _mongoc_read_concern_get_bson (mongoc_read_concern_t *read_concern) { if (!read_concern->frozen) { _mongoc_read_concern_freeze (read_concern); } return &read_concern->compiled; } /** * mongoc_read_concern_freeze: * @read_concern: A mongoc_read_concern_t. * * This is an internal function. * * Freeze the read concern if necessary and encode it into a bson_ts which * represent the raw bson form and the get last error command form. * * You may not modify the read concern further after calling this function. */ static void _mongoc_read_concern_freeze (mongoc_read_concern_t *read_concern) { bson_t *compiled; BSON_ASSERT (read_concern); compiled = &read_concern->compiled; read_concern->frozen = true; bson_init (compiled); BSON_ASSERT (read_concern->level); BSON_APPEND_UTF8 (compiled, "level", read_concern->level); } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-read-concern.h0000664000175000017500000000311612673034026023611 0ustar jmikolajmikola/* * Copyright 2015 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_READ_CONCERN_H #define MONGOC_READ_CONCERN_H #if !defined (MONGOC_INSIDE) && !defined (MONGOC_COMPILATION) # error "Only can be included directly." #endif #include BSON_BEGIN_DECLS #define MONGOC_READ_CONCERN_LEVEL_LOCAL "local" #define MONGOC_READ_CONCERN_LEVEL_MAJORITY "majority" typedef struct _mongoc_read_concern_t mongoc_read_concern_t; mongoc_read_concern_t *mongoc_read_concern_new (void); mongoc_read_concern_t *mongoc_read_concern_copy (const mongoc_read_concern_t *read_concern); void mongoc_read_concern_destroy (mongoc_read_concern_t *read_concern); const char *mongoc_read_concern_get_level (const mongoc_read_concern_t *read_concern); bool mongoc_read_concern_set_level (mongoc_read_concern_t *read_concern, const char *level); BSON_END_DECLS #endif /* MONGOC_READ_CONCERN_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-read-prefs-private.h0000664000175000017500000000327012673034026024752 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_READ_PREFS_PRIVATE_H #define MONGOC_READ_PREFS_PRIVATE_H #if !defined (MONGOC_I_AM_A_DRIVER) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #include #include "mongoc-cluster-private.h" #include "mongoc-read-prefs.h" BSON_BEGIN_DECLS struct _mongoc_read_prefs_t { mongoc_read_mode_t mode; bson_t tags; }; typedef struct _mongoc_apply_read_prefs_result_t { bson_t *query_with_read_prefs; bool query_owned; mongoc_query_flags_t flags; } mongoc_apply_read_prefs_result_t; #define READ_PREFS_RESULT_INIT { NULL, false, MONGOC_QUERY_NONE } void apply_read_preferences (const mongoc_read_prefs_t *read_prefs, const mongoc_server_stream_t *server_stream, const bson_t *query_bson, mongoc_query_flags_t initial_flags, mongoc_apply_read_prefs_result_t *result); void apply_read_prefs_result_cleanup (mongoc_apply_read_prefs_result_t *result); BSON_END_DECLS #endif /* MONGOC_READ_PREFS_PRIVATE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-read-prefs.c0000664000175000017500000002105112673034026023272 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "mongoc-read-prefs-private.h" #include "mongoc-trace.h" mongoc_read_prefs_t * mongoc_read_prefs_new (mongoc_read_mode_t mode) { mongoc_read_prefs_t *read_prefs; read_prefs = (mongoc_read_prefs_t *)bson_malloc0(sizeof *read_prefs); read_prefs->mode = mode; bson_init(&read_prefs->tags); return read_prefs; } mongoc_read_mode_t mongoc_read_prefs_get_mode (const mongoc_read_prefs_t *read_prefs) { return read_prefs ? read_prefs->mode : MONGOC_READ_PRIMARY; } void mongoc_read_prefs_set_mode (mongoc_read_prefs_t *read_prefs, mongoc_read_mode_t mode) { BSON_ASSERT (read_prefs); BSON_ASSERT (mode <= MONGOC_READ_NEAREST); read_prefs->mode = mode; } const bson_t * mongoc_read_prefs_get_tags (const mongoc_read_prefs_t *read_prefs) { BSON_ASSERT (read_prefs); return &read_prefs->tags; } void mongoc_read_prefs_set_tags (mongoc_read_prefs_t *read_prefs, const bson_t *tags) { BSON_ASSERT (read_prefs); bson_destroy(&read_prefs->tags); if (tags) { bson_copy_to(tags, &read_prefs->tags); } else { bson_init(&read_prefs->tags); } } void mongoc_read_prefs_add_tag (mongoc_read_prefs_t *read_prefs, const bson_t *tag) { bson_t empty = BSON_INITIALIZER; char str[16]; int key; BSON_ASSERT (read_prefs); key = bson_count_keys (&read_prefs->tags); bson_snprintf (str, sizeof str, "%d", key); if (tag) { bson_append_document (&read_prefs->tags, str, -1, tag); } else { bson_append_document (&read_prefs->tags, str, -1, &empty); } } bool mongoc_read_prefs_is_valid (const mongoc_read_prefs_t *read_prefs) { BSON_ASSERT (read_prefs); /* * Tags are not supported with PRIMARY mode. */ if (read_prefs->mode == MONGOC_READ_PRIMARY) { if (!bson_empty(&read_prefs->tags)) { return false; } } return true; } void mongoc_read_prefs_destroy (mongoc_read_prefs_t *read_prefs) { if (read_prefs) { bson_destroy(&read_prefs->tags); bson_free(read_prefs); } } mongoc_read_prefs_t * mongoc_read_prefs_copy (const mongoc_read_prefs_t *read_prefs) { mongoc_read_prefs_t *ret = NULL; if (read_prefs) { ret = mongoc_read_prefs_new(read_prefs->mode); bson_copy_to(&read_prefs->tags, &ret->tags); } return ret; } static const char * _get_read_mode_string (mongoc_read_mode_t mode) { switch (mode) { case MONGOC_READ_PRIMARY: return "primary"; case MONGOC_READ_PRIMARY_PREFERRED: return "primaryPreferred"; case MONGOC_READ_SECONDARY: return "secondary"; case MONGOC_READ_SECONDARY_PREFERRED: return "secondaryPreferred"; case MONGOC_READ_NEAREST: return "nearest"; default: return ""; } } /* Update result with the read prefs, following Server Selection Spec. * The driver must have discovered the server is a mongos. */ static void _apply_read_preferences_mongos (const mongoc_read_prefs_t *read_prefs, const bson_t *query_bson, mongoc_apply_read_prefs_result_t *result /* OUT */) { mongoc_read_mode_t mode; const bson_t *tags = NULL; bson_t child; const char *mode_str; mode = mongoc_read_prefs_get_mode (read_prefs); if (read_prefs) { tags = mongoc_read_prefs_get_tags (read_prefs); } /* Server Selection Spec says: * * For mode 'primary', drivers MUST NOT set the slaveOK wire protocol flag * and MUST NOT use $readPreference * * For mode 'secondary', drivers MUST set the slaveOK wire protocol flag and * MUST also use $readPreference * * For mode 'primaryPreferred', drivers MUST set the slaveOK wire protocol * flag and MUST also use $readPreference * * For mode 'secondaryPreferred', drivers MUST set the slaveOK wire protocol * flag. If the read preference contains a non-empty tag_sets parameter, * drivers MUST use $readPreference; otherwise, drivers MUST NOT use * $readPreference * * For mode 'nearest', drivers MUST set the slaveOK wire protocol flag and * MUST also use $readPreference */ if (mode == MONGOC_READ_SECONDARY_PREFERRED && bson_empty0 (tags)) { result->flags |= MONGOC_QUERY_SLAVE_OK; } else if (mode != MONGOC_READ_PRIMARY) { result->flags |= MONGOC_QUERY_SLAVE_OK; /* Server Selection Spec: "When any $ modifier is used, including the * $readPreference modifier, the query MUST be provided using the $query * modifier". * * This applies to commands, too. */ result->query_with_read_prefs = bson_new (); result->query_owned = true; if (bson_has_field (query_bson, "$query")) { bson_concat (result->query_with_read_prefs, query_bson); } else { bson_append_document (result->query_with_read_prefs, "$query", 6, query_bson); } bson_append_document_begin (result->query_with_read_prefs, "$readPreference", 15, &child); mode_str = _get_read_mode_string (mode); bson_append_utf8 (&child, "mode", 4, mode_str, -1); if (!bson_empty0 (tags)) { bson_append_array (&child, "tags", 4, tags); } bson_append_document_end (result->query_with_read_prefs, &child); } } /* *-------------------------------------------------------------------------- * * apply_read_preferences -- * * Update @result based on @read prefs, following the Server Selection * Spec. * * Side effects: * Sets @result->query_with_read_prefs and @result->flags. * *-------------------------------------------------------------------------- */ void apply_read_preferences (const mongoc_read_prefs_t *read_prefs, const mongoc_server_stream_t *server_stream, const bson_t *query_bson, mongoc_query_flags_t initial_flags, mongoc_apply_read_prefs_result_t *result /* OUT */) { mongoc_server_description_type_t server_type; ENTRY; BSON_ASSERT (server_stream); BSON_ASSERT (query_bson); BSON_ASSERT (result); /* default values */ result->query_with_read_prefs = (bson_t *) query_bson; result->query_owned = false; result->flags = initial_flags; server_type = server_stream->sd->type; switch (server_stream->topology_type) { case MONGOC_TOPOLOGY_SINGLE: if (server_type == MONGOC_SERVER_MONGOS) { _apply_read_preferences_mongos (read_prefs, query_bson, result); } else { /* Server Selection Spec: for topology type single and server types * besides mongos, "clients MUST always set the slaveOK wire protocol * flag on reads to ensure that any server type can handle the * request." */ result->flags |= MONGOC_QUERY_SLAVE_OK; } break; case MONGOC_TOPOLOGY_RS_NO_PRIMARY: case MONGOC_TOPOLOGY_RS_WITH_PRIMARY: /* Server Selection Spec: for RS topology types, "For all read * preferences modes except primary, clients MUST set the slaveOK wire * protocol flag to ensure that any suitable server can handle the * request. Clients MUST NOT set the slaveOK wire protocol flag if the * read preference mode is primary. */ if (read_prefs && read_prefs->mode != MONGOC_READ_PRIMARY) { result->flags |= MONGOC_QUERY_SLAVE_OK; } break; case MONGOC_TOPOLOGY_SHARDED: _apply_read_preferences_mongos (read_prefs, query_bson, result); break; case MONGOC_TOPOLOGY_UNKNOWN: case MONGOC_TOPOLOGY_DESCRIPTION_TYPES: default: /* must not call _apply_read_preferences with unknown topology type */ BSON_ASSERT (false); } EXIT; } void apply_read_prefs_result_cleanup (mongoc_apply_read_prefs_result_t *result) { ENTRY; BSON_ASSERT (result); if (result->query_owned) { bson_destroy (result->query_with_read_prefs); } EXIT; } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-read-prefs.h0000664000175000017500000000441212673034026023301 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_READ_PREFS_H #define MONGOC_READ_PREFS_H #if !defined (MONGOC_INSIDE) && !defined (MONGOC_COMPILATION) # error "Only can be included directly." #endif #include BSON_BEGIN_DECLS typedef struct _mongoc_read_prefs_t mongoc_read_prefs_t; typedef enum { MONGOC_READ_PRIMARY = (1 << 0), MONGOC_READ_SECONDARY = (1 << 1), MONGOC_READ_PRIMARY_PREFERRED = (1 << 2) | MONGOC_READ_PRIMARY, MONGOC_READ_SECONDARY_PREFERRED = (1 << 2) | MONGOC_READ_SECONDARY, MONGOC_READ_NEAREST = (1 << 3) | MONGOC_READ_SECONDARY, } mongoc_read_mode_t; mongoc_read_prefs_t *mongoc_read_prefs_new (mongoc_read_mode_t read_mode); mongoc_read_prefs_t *mongoc_read_prefs_copy (const mongoc_read_prefs_t *read_prefs); void mongoc_read_prefs_destroy (mongoc_read_prefs_t *read_prefs); mongoc_read_mode_t mongoc_read_prefs_get_mode (const mongoc_read_prefs_t *read_prefs); void mongoc_read_prefs_set_mode (mongoc_read_prefs_t *read_prefs, mongoc_read_mode_t mode); const bson_t *mongoc_read_prefs_get_tags (const mongoc_read_prefs_t *read_prefs); void mongoc_read_prefs_set_tags (mongoc_read_prefs_t *read_prefs, const bson_t *tags); void mongoc_read_prefs_add_tag (mongoc_read_prefs_t *read_prefs, const bson_t *tag); bool mongoc_read_prefs_is_valid (const mongoc_read_prefs_t *read_prefs); BSON_END_DECLS #endif /* MONGOC_READ_PREFS_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-rpc-private.h0000664000175000017500000001030612673034026023504 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_RPC_PRIVATE_H #define MONGOC_RPC_PRIVATE_H #if !defined (MONGOC_I_AM_A_DRIVER) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #include #include #include "mongoc-array-private.h" #include "mongoc-iovec.h" #include "mongoc-write-concern.h" #include "mongoc-flags.h" BSON_BEGIN_DECLS #define RPC(_name, _code) typedef struct { _code } mongoc_rpc_##_name##_t; #define ENUM_FIELD(_name) uint32_t _name; #define INT32_FIELD(_name) int32_t _name; #define INT64_FIELD(_name) int64_t _name; #define INT64_ARRAY_FIELD(_len, _name) int32_t _len; int64_t *_name; #define CSTRING_FIELD(_name) const char *_name; #define BSON_FIELD(_name) const uint8_t *_name; #define BSON_ARRAY_FIELD(_name) const uint8_t *_name; int32_t _name##_len; #define IOVEC_ARRAY_FIELD(_name) const mongoc_iovec_t *_name; int32_t n_##_name; mongoc_iovec_t _name##_recv; #define RAW_BUFFER_FIELD(_name) const uint8_t *_name; int32_t _name##_len; #define BSON_OPTIONAL(_check, _code) _code #include "op-delete.def" #include "op-get-more.def" #include "op-header.def" #include "op-insert.def" #include "op-kill-cursors.def" #include "op-msg.def" #include "op-query.def" #include "op-reply.def" #include "op-update.def" typedef union { mongoc_rpc_delete_t delete_; mongoc_rpc_get_more_t get_more; mongoc_rpc_header_t header; mongoc_rpc_insert_t insert; mongoc_rpc_kill_cursors_t kill_cursors; mongoc_rpc_msg_t msg; mongoc_rpc_query_t query; mongoc_rpc_reply_t reply; mongoc_rpc_update_t update; } mongoc_rpc_t; BSON_STATIC_ASSERT (sizeof (mongoc_rpc_header_t) == 16); BSON_STATIC_ASSERT (offsetof (mongoc_rpc_header_t, opcode) == offsetof (mongoc_rpc_reply_t, opcode)); #undef RPC #undef ENUM_FIELD #undef INT32_FIELD #undef INT64_FIELD #undef INT64_ARRAY_FIELD #undef CSTRING_FIELD #undef BSON_FIELD #undef BSON_ARRAY_FIELD #undef IOVEC_ARRAY_FIELD #undef BSON_OPTIONAL #undef RAW_BUFFER_FIELD void _mongoc_rpc_gather (mongoc_rpc_t *rpc, mongoc_array_t *array); bool _mongoc_rpc_needs_gle (mongoc_rpc_t *rpc, const mongoc_write_concern_t *write_concern); void _mongoc_rpc_swab_to_le (mongoc_rpc_t *rpc); void _mongoc_rpc_swab_from_le (mongoc_rpc_t *rpc); void _mongoc_rpc_printf (mongoc_rpc_t *rpc); bool _mongoc_rpc_scatter (mongoc_rpc_t *rpc, const uint8_t *buf, size_t buflen); bool _mongoc_rpc_reply_get_first (mongoc_rpc_reply_t *reply, bson_t *bson); void _mongoc_rpc_prep_command (mongoc_rpc_t *rpc, const char *cmd_ns, const bson_t *command, mongoc_query_flags_t flags); bool _mongoc_rpc_parse_command_error(mongoc_rpc_t *rpc, bson_error_t *error); bool _mongoc_rpc_parse_query_error (mongoc_rpc_t *rpc, bson_error_t *error); BSON_END_DECLS #endif /* MONGOC_RPC_PRIVATE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-rpc.c0000664000175000017500000005654212673034026022043 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include "mongoc.h" #include "mongoc-rpc-private.h" #include "mongoc-trace.h" #define RPC(_name, _code) \ static void \ _mongoc_rpc_gather_##_name (mongoc_rpc_##_name##_t *rpc, \ mongoc_array_t *array) \ { \ mongoc_iovec_t iov; \ assert (rpc); \ assert (array); \ rpc->msg_len = 0; \ _code \ } #define INT32_FIELD(_name) \ iov.iov_base = (void *)&rpc->_name; \ iov.iov_len = 4; \ assert (iov.iov_len); \ rpc->msg_len += (int32_t)iov.iov_len; \ _mongoc_array_append_val(array, iov); #define ENUM_FIELD INT32_FIELD #define INT64_FIELD(_name) \ iov.iov_base = (void *)&rpc->_name; \ iov.iov_len = 8; \ assert (iov.iov_len); \ rpc->msg_len += (int32_t)iov.iov_len; \ _mongoc_array_append_val(array, iov); #define CSTRING_FIELD(_name) \ assert (rpc->_name); \ iov.iov_base = (void *)rpc->_name; \ iov.iov_len = strlen(rpc->_name) + 1; \ assert (iov.iov_len); \ rpc->msg_len += (int32_t)iov.iov_len; \ _mongoc_array_append_val(array, iov); #define BSON_FIELD(_name) \ do { \ int32_t __l; \ memcpy(&__l, rpc->_name, 4); \ __l = BSON_UINT32_FROM_LE(__l); \ iov.iov_base = (void *)rpc->_name; \ iov.iov_len = __l; \ assert (iov.iov_len); \ rpc->msg_len += (int32_t)iov.iov_len; \ _mongoc_array_append_val(array, iov); \ } while (0); #define BSON_OPTIONAL(_check, _code) \ if (rpc->_check) { _code } #define BSON_ARRAY_FIELD(_name) \ if (rpc->_name##_len) { \ iov.iov_base = (void *)rpc->_name; \ iov.iov_len = rpc->_name##_len; \ assert (iov.iov_len); \ rpc->msg_len += (int32_t)iov.iov_len; \ _mongoc_array_append_val(array, iov); \ } #define IOVEC_ARRAY_FIELD(_name) \ do { \ ssize_t _i; \ assert (rpc->n_##_name); \ for (_i = 0; _i < rpc->n_##_name; _i++) { \ assert (rpc->_name[_i].iov_len); \ rpc->msg_len += (int32_t)rpc->_name[_i].iov_len; \ _mongoc_array_append_val(array, rpc->_name[_i]); \ } \ } while (0); #define RAW_BUFFER_FIELD(_name) \ iov.iov_base = (void *)rpc->_name; \ iov.iov_len = rpc->_name##_len; \ assert (iov.iov_len); \ rpc->msg_len += (int32_t)iov.iov_len; \ _mongoc_array_append_val(array, iov); #define INT64_ARRAY_FIELD(_len, _name) \ iov.iov_base = (void *)&rpc->_len; \ iov.iov_len = 4; \ assert (iov.iov_len); \ rpc->msg_len += (int32_t)iov.iov_len; \ _mongoc_array_append_val(array, iov); \ iov.iov_base = (void *)rpc->_name; \ iov.iov_len = rpc->_len * 8; \ assert (iov.iov_len); \ rpc->msg_len += (int32_t)iov.iov_len; \ _mongoc_array_append_val(array, iov); #include "op-delete.def" #include "op-get-more.def" #include "op-insert.def" #include "op-kill-cursors.def" #include "op-msg.def" #include "op-query.def" #include "op-reply.def" #include "op-update.def" #undef RPC #undef ENUM_FIELD #undef INT32_FIELD #undef INT64_FIELD #undef INT64_ARRAY_FIELD #undef CSTRING_FIELD #undef BSON_FIELD #undef BSON_ARRAY_FIELD #undef IOVEC_ARRAY_FIELD #undef RAW_BUFFER_FIELD #undef BSON_OPTIONAL #if BSON_BYTE_ORDER == BSON_BIG_ENDIAN #define RPC(_name, _code) \ static void \ _mongoc_rpc_swab_to_le_##_name (mongoc_rpc_##_name##_t *rpc) \ { \ assert (rpc); \ _code \ } #define INT32_FIELD(_name) \ rpc->_name = BSON_UINT32_FROM_LE(rpc->_name); #define ENUM_FIELD INT32_FIELD #define INT64_FIELD(_name) \ rpc->_name = BSON_UINT64_FROM_LE(rpc->_name); #define CSTRING_FIELD(_name) #define BSON_FIELD(_name) #define BSON_ARRAY_FIELD(_name) #define IOVEC_ARRAY_FIELD(_name) #define BSON_OPTIONAL(_check, _code) \ if (rpc->_check) { _code } #define RAW_BUFFER_FIELD(_name) #define INT64_ARRAY_FIELD(_len, _name) \ do { \ ssize_t i; \ for (i = 0; i < rpc->_len; i++) { \ rpc->_name[i] = BSON_UINT64_FROM_LE(rpc->_name[i]); \ } \ rpc->_len = BSON_UINT32_FROM_LE(rpc->_len); \ } while (0); #include "op-delete.def" #include "op-get-more.def" #include "op-insert.def" #include "op-kill-cursors.def" #include "op-msg.def" #include "op-query.def" #include "op-reply.def" #include "op-update.def" #undef RPC #undef INT64_ARRAY_FIELD #define RPC(_name, _code) \ static void \ _mongoc_rpc_swab_from_le_##_name (mongoc_rpc_##_name##_t *rpc) \ { \ assert (rpc); \ _code \ } #define INT64_ARRAY_FIELD(_len, _name) \ do { \ ssize_t i; \ rpc->_len = BSON_UINT32_FROM_LE(rpc->_len); \ for (i = 0; i < rpc->_len; i++) { \ rpc->_name[i] = BSON_UINT64_FROM_LE(rpc->_name[i]); \ } \ } while (0); #include "op-delete.def" #include "op-get-more.def" #include "op-insert.def" #include "op-kill-cursors.def" #include "op-msg.def" #include "op-query.def" #include "op-reply.def" #include "op-update.def" #undef RPC #undef ENUM_FIELD #undef INT32_FIELD #undef INT64_FIELD #undef INT64_ARRAY_FIELD #undef CSTRING_FIELD #undef BSON_FIELD #undef BSON_ARRAY_FIELD #undef IOVEC_ARRAY_FIELD #undef BSON_OPTIONAL #undef RAW_BUFFER_FIELD #endif /* BSON_BYTE_ORDER == BSON_BIG_ENDIAN */ #define RPC(_name, _code) \ static void \ _mongoc_rpc_printf_##_name (mongoc_rpc_##_name##_t *rpc) \ { \ assert (rpc); \ _code \ } #define INT32_FIELD(_name) \ printf(" "#_name" : %d\n", rpc->_name); #define ENUM_FIELD(_name) \ printf(" "#_name" : %u\n", rpc->_name); #define INT64_FIELD(_name) \ printf(" "#_name" : %" PRIi64 "\n", (int64_t)rpc->_name); #define CSTRING_FIELD(_name) \ printf(" "#_name" : %s\n", rpc->_name); #define BSON_FIELD(_name) \ do { \ bson_t b; \ char *s; \ int32_t __l; \ memcpy(&__l, rpc->_name, 4); \ __l = BSON_UINT32_FROM_LE(__l); \ bson_init_static(&b, rpc->_name, __l); \ s = bson_as_json(&b, NULL); \ printf(" "#_name" : %s\n", s); \ bson_free(s); \ bson_destroy(&b); \ } while (0); #define BSON_ARRAY_FIELD(_name) \ do { \ bson_reader_t *__r; \ bool __eof; \ const bson_t *__b; \ __r = bson_reader_new_from_data(rpc->_name, rpc->_name##_len); \ while ((__b = bson_reader_read(__r, &__eof))) { \ char *s = bson_as_json(__b, NULL); \ printf(" "#_name" : %s\n", s); \ bson_free(s); \ } \ bson_reader_destroy(__r); \ } while (0); #define IOVEC_ARRAY_FIELD(_name) \ do { \ ssize_t _i; \ size_t _j; \ for (_i = 0; _i < rpc->n_##_name; _i++) { \ printf(" "#_name" : "); \ for (_j = 0; _j < rpc->_name[_i].iov_len; _j++) { \ uint8_t u; \ u = ((char *)rpc->_name[_i].iov_base)[_j]; \ printf(" %02x", u); \ } \ printf("\n"); \ } \ } while (0); #define BSON_OPTIONAL(_check, _code) \ if (rpc->_check) { _code } #define RAW_BUFFER_FIELD(_name) \ { \ ssize_t __i; \ printf(" "#_name" :"); \ for (__i = 0; __i < rpc->_name##_len; __i++) { \ uint8_t u; \ u = ((char *)rpc->_name)[__i]; \ printf(" %02x", u); \ } \ printf("\n"); \ } #define INT64_ARRAY_FIELD(_len, _name) \ do { \ ssize_t i; \ for (i = 0; i < rpc->_len; i++) { \ printf(" "#_name" : %" PRIi64 "\n", (int64_t)rpc->_name[i]); \ } \ rpc->_len = BSON_UINT32_FROM_LE(rpc->_len); \ } while (0); #include "op-delete.def" #include "op-get-more.def" #include "op-insert.def" #include "op-kill-cursors.def" #include "op-msg.def" #include "op-query.def" #include "op-reply.def" #include "op-update.def" #undef RPC #undef ENUM_FIELD #undef INT32_FIELD #undef INT64_FIELD #undef INT64_ARRAY_FIELD #undef CSTRING_FIELD #undef BSON_FIELD #undef BSON_ARRAY_FIELD #undef IOVEC_ARRAY_FIELD #undef BSON_OPTIONAL #undef RAW_BUFFER_FIELD #define RPC(_name, _code) \ static bool \ _mongoc_rpc_scatter_##_name (mongoc_rpc_##_name##_t *rpc, \ const uint8_t *buf, \ size_t buflen) \ { \ assert (rpc); \ assert (buf); \ assert (buflen); \ _code \ return true; \ } #define INT32_FIELD(_name) \ if (buflen < 4) { \ return false; \ } \ memcpy(&rpc->_name, buf, 4); \ buflen -= 4; \ buf += 4; #define ENUM_FIELD INT32_FIELD #define INT64_FIELD(_name) \ if (buflen < 8) { \ return false; \ } \ memcpy(&rpc->_name, buf, 8); \ buflen -= 8; \ buf += 8; #define INT64_ARRAY_FIELD(_len, _name) \ do { \ size_t needed; \ if (buflen < 4) { \ return false; \ } \ memcpy(&rpc->_len, buf, 4); \ buflen -= 4; \ buf += 4; \ needed = BSON_UINT32_FROM_LE(rpc->_len) * 8; \ if (needed > buflen) { \ return false; \ } \ rpc->_name = (int64_t*)buf; \ buf += needed; \ buflen -= needed; \ } while (0); #define CSTRING_FIELD(_name) \ do { \ size_t __i; \ bool found = false; \ for (__i = 0; __i < buflen; __i++) { \ if (!buf[__i]) { \ rpc->_name = (const char *)buf; \ buflen -= __i + 1; \ buf += __i + 1; \ found = true; \ break; \ } \ } \ if (!found) { \ return false; \ } \ } while (0); #define BSON_FIELD(_name) \ do { \ uint32_t __l; \ if (buflen < 4) { \ return false; \ } \ memcpy(&__l, buf, 4); \ __l = BSON_UINT32_FROM_LE(__l); \ if (__l < 5 || __l > buflen) { \ return false; \ } \ rpc->_name = (uint8_t *)buf; \ buf += __l; \ buflen -= __l; \ } while (0); #define BSON_ARRAY_FIELD(_name) \ rpc->_name = (uint8_t *)buf; \ rpc->_name##_len = (int32_t)buflen; \ buf = NULL; \ buflen = 0; #define BSON_OPTIONAL(_check, _code) \ if (buflen) { \ _code \ } #define IOVEC_ARRAY_FIELD(_name) \ rpc->_name##_recv.iov_base = (void *)buf; \ rpc->_name##_recv.iov_len = buflen; \ rpc->_name = &rpc->_name##_recv; \ rpc->n_##_name = 1; \ buf = NULL; \ buflen = 0; #define RAW_BUFFER_FIELD(_name) \ rpc->_name = (void *)buf; \ rpc->_name##_len = (int32_t)buflen; \ buf = NULL; \ buflen = 0; #include "op-delete.def" #include "op-get-more.def" #include "op-header.def" #include "op-insert.def" #include "op-kill-cursors.def" #include "op-msg.def" #include "op-query.def" #include "op-reply.def" #include "op-update.def" #undef RPC #undef ENUM_FIELD #undef INT32_FIELD #undef INT64_FIELD #undef INT64_ARRAY_FIELD #undef CSTRING_FIELD #undef BSON_FIELD #undef BSON_ARRAY_FIELD #undef IOVEC_ARRAY_FIELD #undef BSON_OPTIONAL #undef RAW_BUFFER_FIELD void _mongoc_rpc_gather (mongoc_rpc_t *rpc, mongoc_array_t *array) { switch ((mongoc_opcode_t)rpc->header.opcode) { case MONGOC_OPCODE_REPLY: _mongoc_rpc_gather_reply(&rpc->reply, array); return; case MONGOC_OPCODE_MSG: _mongoc_rpc_gather_msg(&rpc->msg, array); return; case MONGOC_OPCODE_UPDATE: _mongoc_rpc_gather_update(&rpc->update, array); return; case MONGOC_OPCODE_INSERT: _mongoc_rpc_gather_insert(&rpc->insert, array); return; case MONGOC_OPCODE_QUERY: _mongoc_rpc_gather_query(&rpc->query, array); return; case MONGOC_OPCODE_GET_MORE: _mongoc_rpc_gather_get_more(&rpc->get_more, array); return; case MONGOC_OPCODE_DELETE: _mongoc_rpc_gather_delete(&rpc->delete_, array); return; case MONGOC_OPCODE_KILL_CURSORS: _mongoc_rpc_gather_kill_cursors(&rpc->kill_cursors, array); return; default: MONGOC_WARNING("Unknown rpc type: 0x%08x", rpc->header.opcode); break; } } void _mongoc_rpc_swab_to_le (mongoc_rpc_t *rpc) { #if BSON_BYTE_ORDER != BSON_LITTLE_ENDIAN mongoc_opcode_t opcode; opcode = rpc->header.opcode; switch (opcode) { case MONGOC_OPCODE_REPLY: _mongoc_rpc_swab_to_le_reply(&rpc->reply); break; case MONGOC_OPCODE_MSG: _mongoc_rpc_swab_to_le_msg(&rpc->msg); break; case MONGOC_OPCODE_UPDATE: _mongoc_rpc_swab_to_le_update(&rpc->update); break; case MONGOC_OPCODE_INSERT: _mongoc_rpc_swab_to_le_insert(&rpc->insert); break; case MONGOC_OPCODE_QUERY: _mongoc_rpc_swab_to_le_query(&rpc->query); break; case MONGOC_OPCODE_GET_MORE: _mongoc_rpc_swab_to_le_get_more(&rpc->get_more); break; case MONGOC_OPCODE_DELETE: _mongoc_rpc_swab_to_le_delete(&rpc->delete_); break; case MONGOC_OPCODE_KILL_CURSORS: _mongoc_rpc_swab_to_le_kill_cursors(&rpc->kill_cursors); break; default: MONGOC_WARNING("Unknown rpc type: 0x%08x", opcode); break; } #endif } void _mongoc_rpc_swab_from_le (mongoc_rpc_t *rpc) { #if BSON_BYTE_ORDER != BSON_LITTLE_ENDIAN mongoc_opcode_t opcode; opcode = BSON_UINT32_FROM_LE(rpc->header.opcode); switch (opcode) { case MONGOC_OPCODE_REPLY: _mongoc_rpc_swab_from_le_reply(&rpc->reply); break; case MONGOC_OPCODE_MSG: _mongoc_rpc_swab_from_le_msg(&rpc->msg); break; case MONGOC_OPCODE_UPDATE: _mongoc_rpc_swab_from_le_update(&rpc->update); break; case MONGOC_OPCODE_INSERT: _mongoc_rpc_swab_from_le_insert(&rpc->insert); break; case MONGOC_OPCODE_QUERY: _mongoc_rpc_swab_from_le_query(&rpc->query); break; case MONGOC_OPCODE_GET_MORE: _mongoc_rpc_swab_from_le_get_more(&rpc->get_more); break; case MONGOC_OPCODE_DELETE: _mongoc_rpc_swab_from_le_delete(&rpc->delete_); break; case MONGOC_OPCODE_KILL_CURSORS: _mongoc_rpc_swab_from_le_kill_cursors(&rpc->kill_cursors); break; default: MONGOC_WARNING("Unknown rpc type: 0x%08x", rpc->header.opcode); break; } #endif } void _mongoc_rpc_printf (mongoc_rpc_t *rpc) { switch ((mongoc_opcode_t)rpc->header.opcode) { case MONGOC_OPCODE_REPLY: _mongoc_rpc_printf_reply(&rpc->reply); break; case MONGOC_OPCODE_MSG: _mongoc_rpc_printf_msg(&rpc->msg); break; case MONGOC_OPCODE_UPDATE: _mongoc_rpc_printf_update(&rpc->update); break; case MONGOC_OPCODE_INSERT: _mongoc_rpc_printf_insert(&rpc->insert); break; case MONGOC_OPCODE_QUERY: _mongoc_rpc_printf_query(&rpc->query); break; case MONGOC_OPCODE_GET_MORE: _mongoc_rpc_printf_get_more(&rpc->get_more); break; case MONGOC_OPCODE_DELETE: _mongoc_rpc_printf_delete(&rpc->delete_); break; case MONGOC_OPCODE_KILL_CURSORS: _mongoc_rpc_printf_kill_cursors(&rpc->kill_cursors); break; default: MONGOC_WARNING("Unknown rpc type: 0x%08x", rpc->header.opcode); break; } } bool _mongoc_rpc_scatter (mongoc_rpc_t *rpc, const uint8_t *buf, size_t buflen) { mongoc_opcode_t opcode; memset (rpc, 0, sizeof *rpc); if (BSON_UNLIKELY(buflen < 16)) { return false; } if (!_mongoc_rpc_scatter_header(&rpc->header, buf, 16)) { return false; } opcode = (mongoc_opcode_t)BSON_UINT32_FROM_LE(rpc->header.opcode); switch (opcode) { case MONGOC_OPCODE_REPLY: return _mongoc_rpc_scatter_reply(&rpc->reply, buf, buflen); case MONGOC_OPCODE_MSG: return _mongoc_rpc_scatter_msg(&rpc->msg, buf, buflen); case MONGOC_OPCODE_UPDATE: return _mongoc_rpc_scatter_update(&rpc->update, buf, buflen); case MONGOC_OPCODE_INSERT: return _mongoc_rpc_scatter_insert(&rpc->insert, buf, buflen); case MONGOC_OPCODE_QUERY: return _mongoc_rpc_scatter_query(&rpc->query, buf, buflen); case MONGOC_OPCODE_GET_MORE: return _mongoc_rpc_scatter_get_more(&rpc->get_more, buf, buflen); case MONGOC_OPCODE_DELETE: return _mongoc_rpc_scatter_delete(&rpc->delete_, buf, buflen); case MONGOC_OPCODE_KILL_CURSORS: return _mongoc_rpc_scatter_kill_cursors(&rpc->kill_cursors, buf, buflen); default: MONGOC_WARNING("Unknown rpc type: 0x%08x", opcode); return false; } } bool _mongoc_rpc_reply_get_first (mongoc_rpc_reply_t *reply, bson_t *bson) { int32_t len; if (!reply->documents || reply->documents_len < 4) { return false; } memcpy(&len, reply->documents, 4); len = BSON_UINT32_FROM_LE(len); if (reply->documents_len < len) { return false; } return bson_init_static(bson, reply->documents, len); } /* *-------------------------------------------------------------------------- * * _mongoc_rpc_needs_gle -- * * Checks to see if an rpc requires a getlasterror command to * determine the success of the rpc. * * The write_concern is checked to ensure that the caller wants * to know about a failure. * * Returns: * true if a getlasterror should be delivered; otherwise false. * * Side effects: * None. * *-------------------------------------------------------------------------- */ bool _mongoc_rpc_needs_gle (mongoc_rpc_t *rpc, const mongoc_write_concern_t *write_concern) { switch (rpc->header.opcode) { case MONGOC_OPCODE_REPLY: case MONGOC_OPCODE_QUERY: case MONGOC_OPCODE_MSG: case MONGOC_OPCODE_GET_MORE: case MONGOC_OPCODE_KILL_CURSORS: return false; case MONGOC_OPCODE_INSERT: case MONGOC_OPCODE_UPDATE: case MONGOC_OPCODE_DELETE: default: break; } if (!write_concern || !mongoc_write_concern_get_w(write_concern)) { return false; } return true; } /* *-------------------------------------------------------------------------- * * _mongoc_rpc_prep_command -- * * Prepare an RPC for mongoc_cluster_run_command_rpc. @cmd_ns and * @command must not be freed or modified while the RPC is in use. * * Side effects: * Fills out the RPC, including pointers into @cmd_ns and @command. * *-------------------------------------------------------------------------- */ void _mongoc_rpc_prep_command (mongoc_rpc_t *rpc, const char *cmd_ns, const bson_t *command, mongoc_query_flags_t flags) { rpc->query.msg_len = 0; rpc->query.request_id = 0; rpc->query.response_to = 0; rpc->query.opcode = MONGOC_OPCODE_QUERY; rpc->query.collection = cmd_ns; rpc->query.skip = 0; rpc->query.n_return = -1; rpc->query.fields = NULL; rpc->query.query = bson_get_data (command); /* Find, getMore And killCursors Commands Spec: "When sending a find command * rather than a legacy OP_QUERY find, only the slaveOk flag is honored." * For other cursor-typed commands like aggregate, only slaveOk can be set. * Clear bits except slaveOk; leave slaveOk set only if it is already. */ rpc->query.flags = flags & MONGOC_QUERY_SLAVE_OK; } static void _mongoc_populate_error (const bson_t *doc, bool is_command, bson_error_t *error) { uint32_t code = MONGOC_ERROR_QUERY_FAILURE; bson_iter_t iter; const char *msg = "Unknown query failure"; BSON_ASSERT (doc); if (!error) { return; } if (bson_iter_init_find (&iter, doc, "code") && BSON_ITER_HOLDS_INT32 (&iter)) { code = (uint32_t) bson_iter_int32 (&iter); } if (is_command && ((code == MONGOC_ERROR_PROTOCOL_ERROR) || (code == 13390))) { code = MONGOC_ERROR_QUERY_COMMAND_NOT_FOUND; } if (bson_iter_init_find (&iter, doc, "$err") && BSON_ITER_HOLDS_UTF8 (&iter)) { msg = bson_iter_utf8 (&iter, NULL); } if (is_command && bson_iter_init_find (&iter, doc, "errmsg") && BSON_ITER_HOLDS_UTF8 (&iter)) { msg = bson_iter_utf8 (&iter, NULL); } bson_set_error(error, MONGOC_ERROR_QUERY, code, "%s", msg); } static bool _mongoc_rpc_parse_error (mongoc_rpc_t *rpc, bool is_command, bson_error_t *error /* OUT */) { bson_iter_t iter; bson_t b; ENTRY; BSON_ASSERT (rpc); if (rpc->header.opcode != MONGOC_OPCODE_REPLY) { bson_set_error(error, MONGOC_ERROR_PROTOCOL, MONGOC_ERROR_PROTOCOL_INVALID_REPLY, "Received rpc other than OP_REPLY."); RETURN(true); } if ((rpc->reply.flags & MONGOC_REPLY_QUERY_FAILURE)) { if (_mongoc_rpc_reply_get_first(&rpc->reply, &b)) { _mongoc_populate_error (&b, is_command, error); bson_destroy(&b); } else { bson_set_error(error, MONGOC_ERROR_QUERY, MONGOC_ERROR_QUERY_FAILURE, "Unknown query failure."); } RETURN(true); } else if (is_command) { if (_mongoc_rpc_reply_get_first (&rpc->reply, &b)) { if (bson_iter_init_find (&iter, &b, "ok")) { if (bson_iter_as_bool (&iter)) { RETURN (false); } else { _mongoc_populate_error (&b, is_command, error); bson_destroy (&b); RETURN (true); } } } else { bson_set_error (error, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, "Failed to decode document from the server."); RETURN (true); } } if ((rpc->reply.flags & MONGOC_REPLY_CURSOR_NOT_FOUND)) { bson_set_error(error, MONGOC_ERROR_CURSOR, MONGOC_ERROR_CURSOR_INVALID_CURSOR, "The cursor is invalid or has expired."); RETURN(true); } RETURN(false); } /* *-------------------------------------------------------------------------- * * _mongoc_rpc_parse_command_error -- * * Check if a server OP_REPLY is a command error message. * Optionally fill out a bson_error_t from the server error. * * Returns: * true if the reply is an error message, false otherwise. * * Side effects: * If rpc is an error reply and @error is not NULL, set its * domain, code, and message. * *-------------------------------------------------------------------------- */ bool _mongoc_rpc_parse_command_error (mongoc_rpc_t *rpc, bson_error_t *error) { return _mongoc_rpc_parse_error (rpc, true, error); } /* *-------------------------------------------------------------------------- * * _mongoc_rpc_parse_query_error -- * * Check if a server OP_REPLY is a query error message. * Optionally fill out a bson_error_t from the server error. * * Returns: * true if the reply is an error message, false otherwise. * * Side effects: * If rpc is an error reply and @error is not NULL, set its * domain, code, and message. * *-------------------------------------------------------------------------- */ bool _mongoc_rpc_parse_query_error (mongoc_rpc_t *rpc, bson_error_t *error) { return _mongoc_rpc_parse_error (rpc, false, error); } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-sasl-private.h0000664000175000017500000000473312673034026023671 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_SASL_PRIVATE_H #define MONGOC_SASL_PRIVATE_H #if !defined (MONGOC_I_AM_A_DRIVER) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #include #include #include BSON_BEGIN_DECLS typedef struct _mongoc_sasl_t mongoc_sasl_t; struct _mongoc_sasl_t { sasl_callback_t callbacks [4]; sasl_conn_t *conn; bool done; int step; char *mechanism; char *user; char *pass; char *service_name; char *service_host; sasl_interact_t *interact; }; void _mongoc_sasl_init (mongoc_sasl_t *sasl); void _mongoc_sasl_set_pass (mongoc_sasl_t *sasl, const char *pass); void _mongoc_sasl_set_user (mongoc_sasl_t *sasl, const char *user); void _mongoc_sasl_set_mechanism (mongoc_sasl_t *sasl, const char *mechanism); void _mongoc_sasl_set_service_name (mongoc_sasl_t *sasl, const char *service_name); void _mongoc_sasl_set_service_host (mongoc_sasl_t *sasl, const char *service_host); void _mongoc_sasl_destroy (mongoc_sasl_t *sasl); bool _mongoc_sasl_step (mongoc_sasl_t *sasl, const uint8_t *inbuf, uint32_t inbuflen, uint8_t *outbuf, uint32_t outbufmax, uint32_t *outbuflen, bson_error_t *error); BSON_END_DECLS #endif /* MONGOC_SASL_PRIVATE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-sasl.c0000664000175000017500000002044412673034026022211 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "mongoc-config.h" #ifdef MONGOC_ENABLE_SASL #include #include "mongoc-error.h" #include "mongoc-sasl-private.h" #include "mongoc-util-private.h" #ifndef SASL_CALLBACK_FN # define SASL_CALLBACK_FN(_f) ((int (*) (void))(_f)) #endif void _mongoc_sasl_set_mechanism (mongoc_sasl_t *sasl, const char *mechanism) { BSON_ASSERT (sasl); bson_free (sasl->mechanism); sasl->mechanism = mechanism ? bson_strdup (mechanism) : NULL; } static int _mongoc_sasl_get_pass (mongoc_sasl_t *sasl, int param_id, const char **result, unsigned *result_len) { BSON_ASSERT (sasl); BSON_ASSERT (param_id == SASL_CB_PASS); if (result) { *result = sasl->pass; } if (result_len) { *result_len = sasl->pass ? (unsigned) strlen (sasl->pass) : 0; } return (sasl->pass != NULL) ? SASL_OK : SASL_FAIL; } void _mongoc_sasl_set_pass (mongoc_sasl_t *sasl, const char *pass) { BSON_ASSERT (sasl); bson_free (sasl->pass); sasl->pass = pass ? bson_strdup (pass) : NULL; } static int _mongoc_sasl_get_user (mongoc_sasl_t *sasl, int param_id, const char **result, unsigned *result_len) { BSON_ASSERT (sasl); BSON_ASSERT ((param_id == SASL_CB_USER) || (param_id == SASL_CB_AUTHNAME)); if (result) { *result = sasl->user; } if (result_len) { *result_len = sasl->user ? (unsigned) strlen (sasl->user) : 0; } return (sasl->user != NULL) ? SASL_OK : SASL_FAIL; } void _mongoc_sasl_set_user (mongoc_sasl_t *sasl, const char *user) { BSON_ASSERT (sasl); bson_free (sasl->user); sasl->user = user ? bson_strdup (user) : NULL; } void _mongoc_sasl_set_service_host (mongoc_sasl_t *sasl, const char *service_host) { BSON_ASSERT (sasl); bson_free (sasl->service_host); sasl->service_host = service_host ? bson_strdup (service_host) : NULL; } void _mongoc_sasl_set_service_name (mongoc_sasl_t *sasl, const char *service_name) { BSON_ASSERT (sasl); bson_free (sasl->service_name); sasl->service_name = service_name ? bson_strdup (service_name) : NULL; } void _mongoc_sasl_init (mongoc_sasl_t *sasl) { sasl_callback_t callbacks [] = { { SASL_CB_AUTHNAME, SASL_CALLBACK_FN (_mongoc_sasl_get_user), sasl }, { SASL_CB_USER, SASL_CALLBACK_FN (_mongoc_sasl_get_user), sasl }, { SASL_CB_PASS, SASL_CALLBACK_FN (_mongoc_sasl_get_pass), sasl }, { SASL_CB_LIST_END } }; BSON_ASSERT (sasl); memset (sasl, 0, sizeof *sasl); memcpy (&sasl->callbacks, callbacks, sizeof callbacks); sasl->done = false; sasl->step = 0; sasl->conn = NULL; sasl->mechanism = NULL; sasl->user = NULL; sasl->pass = NULL; sasl->service_name = NULL; sasl->service_host = NULL; sasl->interact = NULL; } void _mongoc_sasl_destroy (mongoc_sasl_t *sasl) { BSON_ASSERT (sasl); if (sasl->conn) { sasl_dispose (&sasl->conn); } bson_free (sasl->user); bson_free (sasl->pass); bson_free (sasl->mechanism); bson_free (sasl->service_name); bson_free (sasl->service_host); } static bool _mongoc_sasl_is_failure (int status, bson_error_t *error) { bool ret = (status < 0); if (ret) { switch (status) { case SASL_NOMEM: bson_set_error (error, MONGOC_ERROR_SASL, status, "SASL Failrue: insufficient memory."); break; case SASL_NOMECH: bson_set_error (error, MONGOC_ERROR_SASL, status, "SASL Failure: failure to negotiate mechanism"); break; case SASL_BADPARAM: bson_set_error (error, MONGOC_ERROR_SASL, status, "Bad parameter supplied. Please file a bug " "with mongo-c-driver."); break; default: bson_set_error (error, MONGOC_ERROR_SASL, status, "SASL Failure: (%d): %s", status, sasl_errstring (status, NULL, NULL)); break; } } return ret; } static bool _mongoc_sasl_start (mongoc_sasl_t *sasl, uint8_t *outbuf, uint32_t outbufmax, uint32_t *outbuflen, bson_error_t *error) { const char *service_name = "mongodb"; const char *service_host = ""; const char *mechanism = NULL; const char *raw = NULL; unsigned raw_len = 0; int status; BSON_ASSERT (sasl); BSON_ASSERT (outbuf); BSON_ASSERT (outbufmax); BSON_ASSERT (outbuflen); if (sasl->service_name) { service_name = sasl->service_name; } if (sasl->service_host) { service_host = sasl->service_host; } status = sasl_client_new (service_name, service_host, NULL, NULL, sasl->callbacks, 0, &sasl->conn); if (_mongoc_sasl_is_failure (status, error)) { return false; } status = sasl_client_start (sasl->conn, sasl->mechanism, &sasl->interact, &raw, &raw_len, &mechanism); if (_mongoc_sasl_is_failure (status, error)) { return false; } if ((0 != strcasecmp (mechanism, "GSSAPI")) && (0 != strcasecmp (mechanism, "PLAIN"))) { bson_set_error (error, MONGOC_ERROR_SASL, SASL_NOMECH, "SASL Failure: invalid mechanism \"%s\"", mechanism); return false; } status = sasl_encode64 (raw, raw_len, (char *)outbuf, outbufmax, outbuflen); if (_mongoc_sasl_is_failure (status, error)) { return false; } return true; } bool _mongoc_sasl_step (mongoc_sasl_t *sasl, const uint8_t *inbuf, uint32_t inbuflen, uint8_t *outbuf, uint32_t outbufmax, uint32_t *outbuflen, bson_error_t *error) { const char *raw = NULL; unsigned rawlen = 0; int status; BSON_ASSERT (sasl); BSON_ASSERT (inbuf); BSON_ASSERT (outbuf); BSON_ASSERT (outbuflen); sasl->step++; if (sasl->step == 1) { return _mongoc_sasl_start (sasl, outbuf, outbufmax, outbuflen, error); } else if (sasl->step >= 10) { bson_set_error (error, MONGOC_ERROR_SASL, SASL_NOTDONE, "SASL Failure: maximum steps detected"); return false; } if (!inbuflen) { bson_set_error (error, MONGOC_ERROR_SASL, MONGOC_ERROR_CLIENT_AUTHENTICATE, "SASL Failure: no payload provided from server."); return false; } status = sasl_decode64 ((char *)inbuf, inbuflen, (char *)outbuf, outbufmax, outbuflen); if (_mongoc_sasl_is_failure (status, error)) { return false; } status = sasl_client_step (sasl->conn, (char *)outbuf, *outbuflen, &sasl->interact, &raw, &rawlen); if (_mongoc_sasl_is_failure (status, error)) { return false; } status = sasl_encode64 (raw, rawlen, (char *)outbuf, outbufmax, outbuflen); if (_mongoc_sasl_is_failure (status, error)) { return false; } return true; } #endif mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-scram-private.h0000664000175000017500000000361512673034026024032 0ustar jmikolajmikola/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if !defined (MONGOC_I_AM_A_DRIVER) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #ifndef MONGOC_SCRAM_PRIVATE_H #define MONGOC_SCRAM_PRIVATE_H #include BSON_BEGIN_DECLS #define MONGOC_SCRAM_HASH_SIZE 20 typedef struct _mongoc_scram_t { bool done; int step; char *user; char *pass; uint8_t salted_password[MONGOC_SCRAM_HASH_SIZE]; char encoded_nonce[48]; int32_t encoded_nonce_len; uint8_t *auth_message; uint32_t auth_messagemax; uint32_t auth_messagelen; } mongoc_scram_t; void _mongoc_scram_startup(); void _mongoc_scram_init (mongoc_scram_t *scram); void _mongoc_scram_set_pass (mongoc_scram_t *scram, const char *pass); void _mongoc_scram_set_user (mongoc_scram_t *scram, const char *user); void _mongoc_scram_destroy (mongoc_scram_t *scram); bool _mongoc_scram_step (mongoc_scram_t *scram, const uint8_t *inbuf, uint32_t inbuflen, uint8_t *outbuf, uint32_t outbufmax, uint32_t *outbuflen, bson_error_t *error); BSON_END_DECLS #endif /* MONGOC_SCRAM_PRIVATE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-scram.c0000664000175000017500000005441612673034026022362 0ustar jmikolajmikola/* Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "mongoc-config.h" #ifdef MONGOC_ENABLE_SSL #include #include "mongoc-error.h" #include "mongoc-scram-private.h" #include "mongoc-rand-private.h" #include "mongoc-util-private.h" #include "mongoc-b64-private.h" #include "mongoc-memcmp-private.h" #include #include #include #define MONGOC_SCRAM_SERVER_KEY "Server Key" #define MONGOC_SCRAM_CLIENT_KEY "Client Key" #define MONGOC_SCRAM_B64_ENCODED_SIZE(n) (2 * n) #define MONGOC_SCRAM_B64_HASH_SIZE \ MONGOC_SCRAM_B64_ENCODED_SIZE (MONGOC_SCRAM_HASH_SIZE) void _mongoc_scram_startup() { mongoc_b64_initialize_rmap(); } void _mongoc_scram_set_pass (mongoc_scram_t *scram, const char *pass) { BSON_ASSERT (scram); if (scram->pass) { bson_zero_free (scram->pass, strlen(scram->pass)); } scram->pass = pass ? bson_strdup (pass) : NULL; } void _mongoc_scram_set_user (mongoc_scram_t *scram, const char *user) { BSON_ASSERT (scram); bson_free (scram->user); scram->user = user ? bson_strdup (user) : NULL; } void _mongoc_scram_init (mongoc_scram_t *scram) { BSON_ASSERT (scram); memset (scram, 0, sizeof *scram); } void _mongoc_scram_destroy (mongoc_scram_t *scram) { BSON_ASSERT (scram); bson_free (scram->user); if (scram->pass) { bson_zero_free (scram->pass, strlen(scram->pass)); } bson_free (scram->auth_message); } static bool _mongoc_scram_buf_write (const char *src, int32_t src_len, uint8_t *outbuf, uint32_t outbufmax, uint32_t *outbuflen) { if (src_len < 0) { src_len = (int32_t) strlen (src); } if (*outbuflen + src_len >= outbufmax) { return false; } memcpy (outbuf + *outbuflen, src, src_len); *outbuflen += src_len; return true; } /* generate client-first-message: * n,a=authzid,n=encoded-username,r=client-nonce * * note that a= is optional, so we aren't dealing with that here */ static bool _mongoc_scram_start (mongoc_scram_t *scram, uint8_t *outbuf, uint32_t outbufmax, uint32_t *outbuflen, bson_error_t *error) { uint8_t nonce[24]; const char *ptr; bool rval = true; BSON_ASSERT (scram); BSON_ASSERT (outbuf); BSON_ASSERT (outbufmax); BSON_ASSERT (outbuflen); /* auth message is as big as the outbuf just because */ scram->auth_message = (uint8_t *)bson_malloc (outbufmax); scram->auth_messagemax = outbufmax; /* the server uses a 24 byte random nonce. so we do as well */ if (1 != _mongoc_rand_bytes (nonce, sizeof (nonce))) { bson_set_error (error, MONGOC_ERROR_SCRAM, MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, "SCRAM Failure: could not generate a cryptographically secure nonce in sasl step 1"); goto FAIL; } scram->encoded_nonce_len = mongoc_b64_ntop (nonce, sizeof (nonce), scram->encoded_nonce, sizeof (scram->encoded_nonce)); if (-1 == scram->encoded_nonce_len) { bson_set_error (error, MONGOC_ERROR_SCRAM, MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, "SCRAM Failure: could not encode nonce"); goto FAIL; } if (!_mongoc_scram_buf_write ("n,,n=", -1, outbuf, outbufmax, outbuflen)) { goto BUFFER; } for (ptr = scram->user; *ptr; ptr++) { /* RFC 5802 specifies that ',' and '=' and encoded as '=2C' and '=3D' * respectively in the user name */ switch (*ptr) { case ',': if (!_mongoc_scram_buf_write ("=2C", -1, outbuf, outbufmax, outbuflen)) { goto BUFFER; } break; case '=': if (!_mongoc_scram_buf_write ("=3D", -1, outbuf, outbufmax, outbuflen)) { goto BUFFER; } break; default: if (!_mongoc_scram_buf_write (ptr, 1, outbuf, outbufmax, outbuflen)) { goto BUFFER; } break; } } if (!_mongoc_scram_buf_write (",r=", -1, outbuf, outbufmax, outbuflen)) { goto BUFFER; } if (!_mongoc_scram_buf_write (scram->encoded_nonce, scram->encoded_nonce_len, outbuf, outbufmax, outbuflen)) { goto BUFFER; } /* we have to keep track of the conversation to create a client proof later * on. This copies the message we're crafting from the 'n=' portion onwards * into a buffer we're managing */ if (!_mongoc_scram_buf_write ((char *)outbuf + 3, *outbuflen - 3, scram->auth_message, scram->auth_messagemax, &scram->auth_messagelen)) { goto BUFFER_AUTH; } if (!_mongoc_scram_buf_write (",", -1, scram->auth_message, scram->auth_messagemax, &scram->auth_messagelen)) { goto BUFFER_AUTH; } goto CLEANUP; BUFFER_AUTH: bson_set_error (error, MONGOC_ERROR_SCRAM, MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, "SCRAM Failure: could not buffer auth message in sasl step1"); goto FAIL; BUFFER: bson_set_error (error, MONGOC_ERROR_SCRAM, MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, "SCRAM Failure: could not buffer sasl step1"); goto FAIL; FAIL: rval = false; CLEANUP: return rval; } /* Compute the SCRAM step Hi() as defined in RFC5802 */ static void _mongoc_scram_salt_password (mongoc_scram_t *scram, const char *password, uint32_t password_len, const uint8_t *salt, uint32_t salt_len, uint32_t iterations) { uint8_t intermediate_digest[MONGOC_SCRAM_HASH_SIZE]; uint8_t start_key[MONGOC_SCRAM_HASH_SIZE]; /* Placeholder for HMAC return size, will always be scram::hashSize for HMAC SHA-1 */ uint32_t hash_len = 0; int i; int k; uint8_t *output = scram->salted_password; memcpy (start_key, salt, salt_len); start_key[salt_len] = 0; start_key[salt_len + 1] = 0; start_key[salt_len + 2] = 0; start_key[salt_len + 3] = 1; /* U1 = HMAC(input, salt + 0001) */ HMAC (EVP_sha1 (), password, password_len, start_key, sizeof (start_key), output, &hash_len); memcpy (intermediate_digest, output, MONGOC_SCRAM_HASH_SIZE); /* intermediateDigest contains Ui and output contains the accumulated XOR:ed result */ for (i = 2; i <= iterations; i++) { HMAC (EVP_sha1 (), password, password_len, intermediate_digest, sizeof (intermediate_digest), intermediate_digest, &hash_len); for (k = 0; k < MONGOC_SCRAM_HASH_SIZE; k++) { output[k] ^= intermediate_digest[k]; } } } static bool _mongoc_scram_sha1 (const unsigned char *input, const size_t input_len, unsigned char *output) { EVP_MD_CTX digest_ctx; bool rval = false; EVP_MD_CTX_init (&digest_ctx); if (1 != EVP_DigestInit_ex (&digest_ctx, EVP_sha1 (), NULL)) { goto cleanup; } if (1 != EVP_DigestUpdate (&digest_ctx, input, input_len)) { goto cleanup; } rval = (1 == EVP_DigestFinal_ex (&digest_ctx, output, NULL)); cleanup: EVP_MD_CTX_cleanup (&digest_ctx); return rval; } static bool _mongoc_scram_generate_client_proof (mongoc_scram_t *scram, uint8_t *outbuf, uint32_t outbufmax, uint32_t *outbuflen) { /* ClientKey := HMAC(saltedPassword, "Client Key") */ uint8_t client_key[MONGOC_SCRAM_HASH_SIZE]; uint8_t stored_key[MONGOC_SCRAM_HASH_SIZE]; uint8_t client_signature[MONGOC_SCRAM_HASH_SIZE]; unsigned char client_proof[MONGOC_SCRAM_HASH_SIZE]; uint32_t hash_len = 0; int i; int r = 0; HMAC (EVP_sha1 (), scram->salted_password, MONGOC_SCRAM_HASH_SIZE, (uint8_t *)MONGOC_SCRAM_CLIENT_KEY, strlen (MONGOC_SCRAM_CLIENT_KEY), client_key, &hash_len); /* StoredKey := H(client_key) */ _mongoc_scram_sha1 (client_key, MONGOC_SCRAM_HASH_SIZE, stored_key); /* ClientSignature := HMAC(StoredKey, AuthMessage) */ HMAC (EVP_sha1 (), stored_key, MONGOC_SCRAM_HASH_SIZE, scram->auth_message, scram->auth_messagelen, client_signature, &hash_len); /* ClientProof := ClientKey XOR ClientSignature */ for (i = 0; i < MONGOC_SCRAM_HASH_SIZE; i++) { client_proof[i] = client_key[i] ^ client_signature[i]; } r = mongoc_b64_ntop (client_proof, sizeof (client_proof), (char *)outbuf + *outbuflen, outbufmax - *outbuflen); if (-1 == r) { return false; } *outbuflen += r; return true; } /* Parse server-first-message of the form: * r=client-nonce|server-nonce,s=user-salt,i=iteration-count * * Generate client-final-message of the form: * c=channel-binding(base64),r=client-nonce|server-nonce,p=client-proof */ static bool _mongoc_scram_step2 (mongoc_scram_t *scram, const uint8_t *inbuf, uint32_t inbuflen, uint8_t *outbuf, uint32_t outbufmax, uint32_t *outbuflen, bson_error_t *error) { uint8_t *val_r = NULL; uint32_t val_r_len; uint8_t *val_s = NULL; uint32_t val_s_len; uint8_t *val_i = NULL; uint32_t val_i_len; uint8_t **current_val; uint32_t *current_val_len; const uint8_t *ptr; const uint8_t *next_comma; char *tmp; char *hashed_password; uint8_t decoded_salt[MONGOC_SCRAM_B64_HASH_SIZE]; int32_t decoded_salt_len; bool rval = true; int iterations; BSON_ASSERT (scram); BSON_ASSERT (outbuf); BSON_ASSERT (outbufmax); BSON_ASSERT (outbuflen); /* all our passwords go through md5 thanks to MONGODB-CR */ tmp = bson_strdup_printf ("%s:mongo:%s", scram->user, scram->pass); hashed_password = _mongoc_hex_md5 (tmp); bson_zero_free (tmp, strlen(tmp)); /* we need all of the incoming message for the final client proof */ if (!_mongoc_scram_buf_write ((char *)inbuf, inbuflen, scram->auth_message, scram->auth_messagemax, &scram->auth_messagelen)) { goto BUFFER_AUTH; } if (!_mongoc_scram_buf_write (",", -1, scram->auth_message, scram->auth_messagemax, &scram->auth_messagelen)) { goto BUFFER_AUTH; } for (ptr = inbuf; ptr < inbuf + inbuflen; ) { switch (*ptr) { case 'r': current_val = &val_r; current_val_len = &val_r_len; break; case 's': current_val = &val_s; current_val_len = &val_s_len; break; case 'i': current_val = &val_i; current_val_len = &val_i_len; break; default: bson_set_error (error, MONGOC_ERROR_SCRAM, MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, "SCRAM Failure: unknown key (%c) in sasl step 2", *ptr); goto FAIL; break; } ptr++; if (*ptr != '=') { bson_set_error (error, MONGOC_ERROR_SCRAM, MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, "SCRAM Failure: invalid parse state in sasl step 2"); goto FAIL; } ptr++; next_comma = (const uint8_t*)memchr (ptr, ',', (inbuf + inbuflen) - ptr); if (next_comma) { *current_val_len = (uint32_t) (next_comma - ptr); } else { *current_val_len = (uint32_t) ((inbuf + inbuflen) - ptr); } *current_val = (uint8_t *)bson_malloc (*current_val_len + 1); memcpy (*current_val, ptr, *current_val_len); (*current_val)[*current_val_len] = '\0'; if (next_comma) { ptr = next_comma + 1; } else { break; } } if (!val_r) { bson_set_error (error, MONGOC_ERROR_SCRAM, MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, "SCRAM Failure: no r param in sasl step 2"); goto FAIL; } if (!val_s) { bson_set_error (error, MONGOC_ERROR_SCRAM, MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, "SCRAM Failure: no s param in sasl step 2"); goto FAIL; } if (!val_i) { bson_set_error (error, MONGOC_ERROR_SCRAM, MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, "SCRAM Failure: no i param in sasl step 2"); goto FAIL; } /* verify our nonce */ if (val_r_len < scram->encoded_nonce_len || mongoc_memcmp (val_r, scram->encoded_nonce, scram->encoded_nonce_len)) { bson_set_error (error, MONGOC_ERROR_SCRAM, MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, "SCRAM Failure: client nonce not repeated in sasl step 2"); } *outbuflen = 0; if (!_mongoc_scram_buf_write ("c=biws,r=", -1, outbuf, outbufmax, outbuflen)) { goto BUFFER; } if (!_mongoc_scram_buf_write ((char *)val_r, val_r_len, outbuf, outbufmax, outbuflen)) { goto BUFFER; } if (!_mongoc_scram_buf_write ((char *)outbuf, *outbuflen, scram->auth_message, scram->auth_messagemax, &scram->auth_messagelen)) { goto BUFFER_AUTH; } if (!_mongoc_scram_buf_write (",p=", -1, outbuf, outbufmax, outbuflen)) { goto BUFFER; } decoded_salt_len = mongoc_b64_pton ((char *)val_s, decoded_salt, sizeof (decoded_salt)); if (-1 == decoded_salt_len) { bson_set_error (error, MONGOC_ERROR_SCRAM, MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, "SCRAM Failure: unable to decode salt in sasl step2"); goto FAIL; } if (16 != decoded_salt_len) { bson_set_error (error, MONGOC_ERROR_SCRAM, MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, "SCRAM Failure: invalid salt length of %d in sasl step2", decoded_salt_len); goto FAIL; } iterations = (int) bson_ascii_strtoll ((char *)val_i, &tmp, 10); /* tmp holds the location of the failed to parse character. So if it's * null, we got to the end of the string and didn't have a parse error */ if (*tmp) { bson_set_error (error, MONGOC_ERROR_SCRAM, MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, "SCRAM Failure: unable to parse iterations in sasl step2"); goto FAIL; } _mongoc_scram_salt_password (scram, hashed_password, (uint32_t) strlen ( hashed_password), decoded_salt, decoded_salt_len, iterations); _mongoc_scram_generate_client_proof (scram, outbuf, outbufmax, outbuflen); goto CLEANUP; BUFFER_AUTH: bson_set_error (error, MONGOC_ERROR_SCRAM, MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, "SCRAM Failure: could not buffer auth message in sasl step2"); goto FAIL; BUFFER: bson_set_error (error, MONGOC_ERROR_SCRAM, MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, "SCRAM Failure: could not buffer sasl step2"); goto FAIL; FAIL: rval = false; CLEANUP: bson_free (val_r); bson_free (val_s); bson_free (val_i); if (hashed_password) { bson_zero_free (hashed_password, strlen(hashed_password)); } return rval; } static bool _mongoc_scram_verify_server_signature (mongoc_scram_t *scram, uint8_t *verification, uint32_t len) { /* ServerKey := HMAC(SaltedPassword, "Server Key") */ uint32_t hash_len; uint8_t server_key[MONGOC_SCRAM_HASH_SIZE]; char encoded_server_signature[MONGOC_SCRAM_B64_HASH_SIZE]; int32_t encoded_server_signature_len; uint8_t server_signature[MONGOC_SCRAM_HASH_SIZE]; HMAC (EVP_sha1 (), scram->salted_password, MONGOC_SCRAM_HASH_SIZE, (uint8_t *)MONGOC_SCRAM_SERVER_KEY, strlen (MONGOC_SCRAM_SERVER_KEY), server_key, &hash_len); /* ServerSignature := HMAC(ServerKey, AuthMessage) */ HMAC (EVP_sha1 (), server_key, MONGOC_SCRAM_HASH_SIZE, scram->auth_message, scram->auth_messagelen, server_signature, &hash_len); encoded_server_signature_len = mongoc_b64_ntop (server_signature, sizeof (server_signature), encoded_server_signature, sizeof (encoded_server_signature)); if (encoded_server_signature_len == -1) { return false; } return (len == encoded_server_signature_len) && (mongoc_memcmp (verification, encoded_server_signature, len) == 0); } static bool _mongoc_scram_step3 (mongoc_scram_t *scram, const uint8_t *inbuf, uint32_t inbuflen, uint8_t *outbuf, uint32_t outbufmax, uint32_t *outbuflen, bson_error_t *error) { uint8_t *val_e = NULL; uint32_t val_e_len; uint8_t *val_v = NULL; uint32_t val_v_len; uint8_t **current_val; uint32_t *current_val_len; const uint8_t *ptr; const uint8_t *next_comma; bool rval = true; BSON_ASSERT (scram); BSON_ASSERT (outbuf); BSON_ASSERT (outbufmax); BSON_ASSERT (outbuflen); for (ptr = inbuf; ptr < inbuf + inbuflen; ) { switch (*ptr) { case 'e': current_val = &val_e; current_val_len = &val_e_len; break; case 'v': current_val = &val_v; current_val_len = &val_v_len; break; default: bson_set_error (error, MONGOC_ERROR_SCRAM, MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, "SCRAM Failure: unknown key (%c) in sasl step 3", *ptr); goto FAIL; break; } ptr++; if (*ptr != '=') { bson_set_error (error, MONGOC_ERROR_SCRAM, MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, "SCRAM Failure: invalid parse state in sasl step 3"); goto FAIL; } ptr++; next_comma = (const uint8_t*)memchr (ptr, ',', (inbuf + inbuflen) - ptr); if (next_comma) { *current_val_len = (uint32_t) (next_comma - ptr); } else { *current_val_len = (uint32_t) ((inbuf + inbuflen) - ptr); } *current_val = (uint8_t *)bson_malloc (*current_val_len + 1); memcpy (*current_val, ptr, *current_val_len); (*current_val)[*current_val_len] = '\0'; if (next_comma) { ptr = next_comma + 1; } else { break; } } *outbuflen = 0; if (val_e) { bson_set_error (error, MONGOC_ERROR_SCRAM, MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, "SCRAM Failure: authentication failure in sasl step 3 : %s", val_e); goto FAIL; } if (!val_v) { bson_set_error (error, MONGOC_ERROR_SCRAM, MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, "SCRAM Failure: no v param in sasl step 3"); goto FAIL; } if (!_mongoc_scram_verify_server_signature (scram, val_v, val_v_len)) { bson_set_error (error, MONGOC_ERROR_SCRAM, MONGOC_ERROR_SCRAM_PROTOCOL_ERROR, "SCRAM Failure: could not verify server signature in sasl step 3"); goto FAIL; } goto CLEANUP; FAIL: rval = false; CLEANUP: bson_free (val_e); bson_free (val_v); return rval; } bool _mongoc_scram_step (mongoc_scram_t *scram, const uint8_t *inbuf, uint32_t inbuflen, uint8_t *outbuf, uint32_t outbufmax, uint32_t *outbuflen, bson_error_t *error) { BSON_ASSERT (scram); BSON_ASSERT (inbuf); BSON_ASSERT (outbuf); BSON_ASSERT (outbuflen); scram->step++; switch (scram->step) { case 1: return _mongoc_scram_start (scram, outbuf, outbufmax, outbuflen, error); break; case 2: return _mongoc_scram_step2 (scram, inbuf, inbuflen, outbuf, outbufmax, outbuflen, error); break; case 3: return _mongoc_scram_step3 (scram, inbuf, inbuflen, outbuf, outbufmax, outbuflen, error); break; default: bson_set_error (error, MONGOC_ERROR_SCRAM, MONGOC_ERROR_SCRAM_NOT_DONE, "SCRAM Failure: maximum steps detected"); return false; break; } return true; } #endif mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-server-description-private.h0000664000175000017500000001054112673034026026550 0ustar jmikolajmikola/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_SERVER_DESCRIPTION_PRIVATE_H #define MONGOC_SERVER_DESCRIPTION_PRIVATE_H #include "mongoc-server-description.h" #define MONGOC_DEFAULT_WIRE_VERSION 0 #define MONGOC_DEFAULT_WRITE_BATCH_SIZE 1000 #define MONGOC_DEFAULT_BSON_OBJ_SIZE 16 * 1024 * 1024 #define MONGOC_DEFAULT_MAX_MSG_SIZE 48000000 /* represent a server or topology with no replica set config version */ #define MONGOC_NO_SET_VERSION -1 typedef enum { MONGOC_SERVER_UNKNOWN, MONGOC_SERVER_STANDALONE, MONGOC_SERVER_MONGOS, MONGOC_SERVER_POSSIBLE_PRIMARY, MONGOC_SERVER_RS_PRIMARY, MONGOC_SERVER_RS_SECONDARY, MONGOC_SERVER_RS_ARBITER, MONGOC_SERVER_RS_OTHER, MONGOC_SERVER_RS_GHOST, MONGOC_SERVER_DESCRIPTION_TYPES, } mongoc_server_description_type_t; struct _mongoc_server_description_t { uint32_t id; mongoc_host_list_t host; int64_t round_trip_time; bson_t last_is_master; bool has_is_master; const char *connection_address; const char *me; /* The following fields are filled from the last_is_master and are zeroed on * parse. So order matters here. DON'T move set_name */ const char *set_name; bson_error_t error; mongoc_server_description_type_t type; int32_t min_wire_version; int32_t max_wire_version; int32_t max_msg_size; int32_t max_bson_obj_size; int32_t max_write_batch_size; bson_t hosts; bson_t passives; bson_t arbiters; bson_t tags; const char *current_primary; int64_t set_version; bson_oid_t election_id; }; void mongoc_server_description_init (mongoc_server_description_t *sd, const char *address, uint32_t id); bool mongoc_server_description_has_rs_member (mongoc_server_description_t *description, const char *address); bool mongoc_server_description_has_set_version (mongoc_server_description_t *description); bool mongoc_server_description_has_election_id (mongoc_server_description_t *description); void mongoc_server_description_cleanup (mongoc_server_description_t *sd); void mongoc_server_description_reset (mongoc_server_description_t *sd); void mongoc_server_description_set_state (mongoc_server_description_t *description, mongoc_server_description_type_t type); void mongoc_server_description_set_set_version (mongoc_server_description_t *description, int64_t set_version); void mongoc_server_description_set_election_id (mongoc_server_description_t *description, const bson_oid_t *election_id); void mongoc_server_description_update_rtt (mongoc_server_description_t *server, int64_t new_time); void mongoc_server_description_handle_ismaster ( mongoc_server_description_t *sd, const bson_t *reply, int64_t rtt_msec, bson_error_t *error); size_t mongoc_server_description_filter_eligible ( mongoc_server_description_t **descriptions, size_t description_len, const mongoc_read_prefs_t *read_prefs); #endif mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-server-description.c0000664000175000017500000004717312673034026025106 0ustar jmikolajmikola/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "mongoc-host-list.h" #include "mongoc-host-list-private.h" #include "mongoc-read-prefs.h" #include "mongoc-server-description-private.h" #include "mongoc-trace.h" #include "mongoc-uri.h" #include "mongoc-util-private.h" #include #define ALPHA 0.2 static uint8_t kMongocEmptyBson[] = { 5, 0, 0, 0, 0 }; static bson_oid_t kObjectIdZero = { {0} }; /* Destroy allocated resources within @description, but don't free it */ void mongoc_server_description_cleanup (mongoc_server_description_t *sd) { BSON_ASSERT(sd); bson_destroy (&sd->last_is_master); } /* Reset fields inside this sd, but keep same id, host information, and RTT, and leave ismaster in empty inited state */ void mongoc_server_description_reset (mongoc_server_description_t *sd) { BSON_ASSERT(sd); /* set other fields to default or empty states. election_id is zeroed. */ memset (&sd->set_name, 0, sizeof (*sd) - ((char*)&sd->set_name - (char*)sd)); sd->set_name = NULL; sd->type = MONGOC_SERVER_UNKNOWN; sd->min_wire_version = MONGOC_DEFAULT_WIRE_VERSION; sd->max_wire_version = MONGOC_DEFAULT_WIRE_VERSION; sd->max_msg_size = MONGOC_DEFAULT_MAX_MSG_SIZE; sd->max_bson_obj_size = MONGOC_DEFAULT_BSON_OBJ_SIZE; sd->max_write_batch_size = MONGOC_DEFAULT_WRITE_BATCH_SIZE; /* always leave last ismaster in an init-ed state until we destroy sd */ bson_destroy (&sd->last_is_master); bson_init (&sd->last_is_master); sd->has_is_master = false; } /* *-------------------------------------------------------------------------- * * mongoc_server_description_init -- * * Initialize a new server_description_t. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void mongoc_server_description_init (mongoc_server_description_t *sd, const char *address, uint32_t id) { ENTRY; BSON_ASSERT (sd); BSON_ASSERT (address); memset (sd, 0, sizeof *sd); sd->id = id; sd->type = MONGOC_SERVER_UNKNOWN; sd->round_trip_time = -1; sd->set_name = NULL; sd->set_version = MONGOC_NO_SET_VERSION; sd->current_primary = NULL; if (!_mongoc_host_list_from_string(&sd->host, address)) { MONGOC_WARNING("Failed to parse uri for %s", address); return; } sd->connection_address = sd->host.host_and_port; sd->me = NULL; sd->min_wire_version = MONGOC_DEFAULT_WIRE_VERSION; sd->max_wire_version = MONGOC_DEFAULT_WIRE_VERSION; sd->max_msg_size = MONGOC_DEFAULT_MAX_MSG_SIZE; sd->max_bson_obj_size = MONGOC_DEFAULT_BSON_OBJ_SIZE; sd->max_write_batch_size = MONGOC_DEFAULT_WRITE_BATCH_SIZE; bson_init_static (&sd->hosts, kMongocEmptyBson, sizeof (kMongocEmptyBson)); bson_init_static (&sd->passives, kMongocEmptyBson, sizeof (kMongocEmptyBson)); bson_init_static (&sd->arbiters, kMongocEmptyBson, sizeof (kMongocEmptyBson)); bson_init_static (&sd->tags, kMongocEmptyBson, sizeof (kMongocEmptyBson)); bson_init (&sd->last_is_master); EXIT; } /* *-------------------------------------------------------------------------- * * mongoc_server_description_destroy -- * * Destroy allocated resources within @description and free * @description. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void mongoc_server_description_destroy (mongoc_server_description_t *description) { ENTRY; mongoc_server_description_cleanup(description); bson_free(description); EXIT; } /* *-------------------------------------------------------------------------- * * mongoc_server_description_has_rs_member -- * * Return true if this address is included in server's list of rs * members, false otherwise. * * Returns: * true, false * * Side effects: * None * *-------------------------------------------------------------------------- */ bool mongoc_server_description_has_rs_member(mongoc_server_description_t *server, const char *address) { bson_iter_t member_iter; const bson_t *rs_members[3]; int i; if (server->type != MONGOC_SERVER_UNKNOWN) { rs_members[0] = &server->hosts; rs_members[1] = &server->arbiters; rs_members[2] = &server->passives; for (i = 0; i < 3; i++) { bson_iter_init (&member_iter, rs_members[i]); while (bson_iter_next (&member_iter)) { if (strcasecmp (address, bson_iter_utf8 (&member_iter, NULL)) == 0) { return true; } } } } return false; } /* *-------------------------------------------------------------------------- * * mongoc_server_description_has_set_version -- * * Did this server's ismaster response have a "setVersion" field? * * Returns: * True if the server description's setVersion is set. * *-------------------------------------------------------------------------- */ bool mongoc_server_description_has_set_version (mongoc_server_description_t *description) { return description->set_version != MONGOC_NO_SET_VERSION; } /* *-------------------------------------------------------------------------- * * mongoc_server_description_has_election_id -- * * Did this server's ismaster response have an "electionId" field? * * Returns: * True if the server description's electionId is set. * *-------------------------------------------------------------------------- */ bool mongoc_server_description_has_election_id (mongoc_server_description_t *description) { return 0 != bson_oid_compare (&description->election_id, &kObjectIdZero); } /* *-------------------------------------------------------------------------- * * mongoc_server_description_id -- * * Get the id of this server. * * Returns: * Server's id. * *-------------------------------------------------------------------------- */ uint32_t mongoc_server_description_id (mongoc_server_description_t *description) { return description->id; } /* *-------------------------------------------------------------------------- * * mongoc_server_description_host -- * * Return a reference to the host associated with this server description. * * Returns: * A mongoc_host_list_t *, this server description's host. * *-------------------------------------------------------------------------- */ mongoc_host_list_t * mongoc_server_description_host (mongoc_server_description_t *description) { return &description->host; } /* *-------------------------------------------------------------------------- * * mongoc_server_description_set_state -- * * Set the server description's server type. * *-------------------------------------------------------------------------- */ void mongoc_server_description_set_state (mongoc_server_description_t *description, mongoc_server_description_type_t type) { description->type = type; } /* *-------------------------------------------------------------------------- * * mongoc_server_description_set_set_version -- * * Set the replica set version of this server. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void mongoc_server_description_set_set_version (mongoc_server_description_t *description, int64_t set_version) { description->set_version = set_version; } /* *-------------------------------------------------------------------------- * * mongoc_server_description_set_election_id -- * * Set the election_id of this server. Copies the given ObjectId or, * if it is NULL, zeroes description's election_id. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void mongoc_server_description_set_election_id (mongoc_server_description_t *description, const bson_oid_t *election_id) { if (election_id) { bson_oid_copy_unsafe (election_id, &description->election_id); } else { bson_oid_copy_unsafe (&kObjectIdZero, &description->election_id); } } /* *------------------------------------------------------------------------- * * mongoc_server_description_update_rtt -- * * Calculate this server's rtt calculation using an exponentially- * weighted moving average formula. * * Side effects: * None. * *------------------------------------------------------------------------- */ void mongoc_server_description_update_rtt (mongoc_server_description_t *server, int64_t new_time) { if (server->round_trip_time == -1) { server->round_trip_time = new_time; } else { server->round_trip_time = ALPHA * new_time + (1 - ALPHA) * server->round_trip_time; } } /* *------------------------------------------------------------------------- * * Called during SDAM, from topology description's ismaster handler. * *------------------------------------------------------------------------- */ void mongoc_server_description_handle_ismaster ( mongoc_server_description_t *sd, const bson_t *ismaster_response, int64_t rtt_msec, bson_error_t *error) { bson_iter_t iter; bool is_master = false; bool is_shard = false; bool is_secondary = false; bool is_arbiter = false; bool is_replicaset = false; bool is_hidden = false; const uint8_t *bytes; uint32_t len; int num_keys = 0; ENTRY; BSON_ASSERT (sd); mongoc_server_description_reset (sd); if (!ismaster_response) { EXIT; } bson_destroy (&sd->last_is_master); bson_copy_to (ismaster_response, &sd->last_is_master); sd->has_is_master = true; bson_iter_init (&iter, &sd->last_is_master); while (bson_iter_next (&iter)) { num_keys++; if (strcmp ("ok", bson_iter_key (&iter)) == 0) { /* ismaster responses never have ok: 0, but spec requires we check */ if (! bson_iter_as_bool (&iter)) goto failure; } else if (strcmp ("ismaster", bson_iter_key (&iter)) == 0) { if (! BSON_ITER_HOLDS_BOOL (&iter)) goto failure; is_master = bson_iter_bool (&iter); } else if (strcmp ("me", bson_iter_key (&iter)) == 0) { if (! BSON_ITER_HOLDS_UTF8 (&iter)) goto failure; sd->me = bson_iter_utf8 (&iter, NULL); } else if (strcmp ("maxMessageSizeBytes", bson_iter_key (&iter)) == 0) { if (! BSON_ITER_HOLDS_INT32 (&iter)) goto failure; sd->max_msg_size = bson_iter_int32 (&iter); } else if (strcmp ("maxBsonObjectSize", bson_iter_key (&iter)) == 0) { if (! BSON_ITER_HOLDS_INT32 (&iter)) goto failure; sd->max_bson_obj_size = bson_iter_int32 (&iter); } else if (strcmp ("maxWriteBatchSize", bson_iter_key (&iter)) == 0) { if (! BSON_ITER_HOLDS_INT32 (&iter)) goto failure; sd->max_write_batch_size = bson_iter_int32 (&iter); } else if (strcmp ("minWireVersion", bson_iter_key (&iter)) == 0) { if (! BSON_ITER_HOLDS_INT32 (&iter)) goto failure; sd->min_wire_version = bson_iter_int32 (&iter); } else if (strcmp ("maxWireVersion", bson_iter_key (&iter)) == 0) { if (! BSON_ITER_HOLDS_INT32 (&iter)) goto failure; sd->max_wire_version = bson_iter_int32 (&iter); } else if (strcmp ("msg", bson_iter_key (&iter)) == 0) { if (! BSON_ITER_HOLDS_UTF8 (&iter)) goto failure; is_shard = !!bson_iter_utf8 (&iter, NULL); } else if (strcmp ("setName", bson_iter_key (&iter)) == 0) { if (! BSON_ITER_HOLDS_UTF8 (&iter)) goto failure; sd->set_name = bson_iter_utf8 (&iter, NULL); } else if (strcmp ("setVersion", bson_iter_key (&iter)) == 0) { mongoc_server_description_set_set_version (sd, bson_iter_as_int64 (&iter)); } else if (strcmp ("electionId", bson_iter_key (&iter)) == 0) { if (! BSON_ITER_HOLDS_OID (&iter)) goto failure; mongoc_server_description_set_election_id (sd, bson_iter_oid (&iter)); } else if (strcmp ("secondary", bson_iter_key (&iter)) == 0) { if (! BSON_ITER_HOLDS_BOOL (&iter)) goto failure; is_secondary = bson_iter_bool (&iter); } else if (strcmp ("hosts", bson_iter_key (&iter)) == 0) { if (! BSON_ITER_HOLDS_ARRAY (&iter)) goto failure; bson_iter_array (&iter, &len, &bytes); bson_init_static (&sd->hosts, bytes, len); } else if (strcmp ("passives", bson_iter_key (&iter)) == 0) { if (! BSON_ITER_HOLDS_ARRAY (&iter)) goto failure; bson_iter_array (&iter, &len, &bytes); bson_init_static (&sd->passives, bytes, len); } else if (strcmp ("arbiters", bson_iter_key (&iter)) == 0) { if (! BSON_ITER_HOLDS_ARRAY (&iter)) goto failure; bson_iter_array (&iter, &len, &bytes); bson_init_static (&sd->arbiters, bytes, len); } else if (strcmp ("primary", bson_iter_key (&iter)) == 0) { if (! BSON_ITER_HOLDS_UTF8 (&iter)) goto failure; sd->current_primary = bson_iter_utf8 (&iter, NULL); } else if (strcmp ("arbiterOnly", bson_iter_key (&iter)) == 0) { if (! BSON_ITER_HOLDS_BOOL (&iter)) goto failure; is_arbiter = bson_iter_bool (&iter); } else if (strcmp ("isreplicaset", bson_iter_key (&iter)) == 0) { if (! BSON_ITER_HOLDS_BOOL (&iter)) goto failure; is_replicaset = bson_iter_bool (&iter); } else if (strcmp ("tags", bson_iter_key (&iter)) == 0) { if (! BSON_ITER_HOLDS_DOCUMENT (&iter)) goto failure; bson_iter_document (&iter, &len, &bytes); bson_init_static (&sd->tags, bytes, len); } else if (strcmp ("hidden", bson_iter_key (&iter)) == 0) { is_hidden = bson_iter_bool (&iter); } } if (is_shard) { sd->type = MONGOC_SERVER_MONGOS; } else if (sd->set_name) { if (is_hidden) { sd->type = MONGOC_SERVER_RS_OTHER; } else if (is_master) { sd->type = MONGOC_SERVER_RS_PRIMARY; } else if (is_secondary) { sd->type = MONGOC_SERVER_RS_SECONDARY; } else if (is_arbiter) { sd->type = MONGOC_SERVER_RS_ARBITER; } else { sd->type = MONGOC_SERVER_RS_OTHER; } } else if (is_replicaset) { sd->type = MONGOC_SERVER_RS_GHOST; } else if (num_keys > 0) { sd->type = MONGOC_SERVER_STANDALONE; } else { sd->type = MONGOC_SERVER_UNKNOWN; } mongoc_server_description_update_rtt(sd, rtt_msec); EXIT; failure: sd->type = MONGOC_SERVER_UNKNOWN; sd->round_trip_time = -1; EXIT; } /* *------------------------------------------------------------------------- * * mongoc_server_description_new_copy -- * * A copy of a server description that you must destroy, or NULL. * *------------------------------------------------------------------------- */ mongoc_server_description_t * mongoc_server_description_new_copy (const mongoc_server_description_t *description) { mongoc_server_description_t *copy; if (!description) { return NULL; } copy = (mongoc_server_description_t *)bson_malloc0(sizeof (*copy)); copy->id = description->id; memcpy (©->host, &description->host, sizeof (copy->host)); copy->round_trip_time = -1; copy->connection_address = copy->host.host_and_port; /* wait for handle_ismaster to fill these in properly */ copy->has_is_master = false; copy->set_version = MONGOC_NO_SET_VERSION; bson_init_static (©->hosts, kMongocEmptyBson, sizeof (kMongocEmptyBson)); bson_init_static (©->passives, kMongocEmptyBson, sizeof (kMongocEmptyBson)); bson_init_static (©->arbiters, kMongocEmptyBson, sizeof (kMongocEmptyBson)); bson_init_static (©->tags, kMongocEmptyBson, sizeof (kMongocEmptyBson)); bson_init (©->last_is_master); if (description->has_is_master) { mongoc_server_description_handle_ismaster (copy, &description->last_is_master, description->round_trip_time, NULL); } /* Preserve the error */ memcpy (©->error, &description->error, sizeof copy->error); return copy; } /* *------------------------------------------------------------------------- * * mongoc_server_description_filter_eligible -- * * Given a set of server descriptions, determine which are eligible * as per the Server Selection spec. Determines the number of * eligible servers, and sets any servers that are NOT eligible to * NULL in the descriptions set. * * Returns: * Number of eligible servers found. * *------------------------------------------------------------------------- */ size_t mongoc_server_description_filter_eligible ( mongoc_server_description_t **descriptions, size_t description_len, const mongoc_read_prefs_t *read_prefs) { const bson_t *rp_tags; bson_iter_t rp_tagset_iter; bson_iter_t rp_iter; bson_iter_t sd_iter; uint32_t rp_len; uint32_t sd_len; const char *rp_val; const char *sd_val; bool *sd_matched = NULL; size_t found; size_t i; size_t rval = 0; if (!read_prefs) { /* NULL read_prefs is PRIMARY, no tags to filter by */ return description_len; } rp_tags = mongoc_read_prefs_get_tags (read_prefs); if (bson_count_keys (rp_tags) == 0) { return description_len; } sd_matched = (bool *) bson_malloc0 (sizeof(bool) * description_len); bson_iter_init (&rp_tagset_iter, rp_tags); /* for each read preference tagset */ while (bson_iter_next (&rp_tagset_iter)) { found = description_len; for (i = 0; i < description_len; i++) { sd_matched[i] = true; bson_iter_recurse (&rp_tagset_iter, &rp_iter); while (bson_iter_next (&rp_iter)) { /* TODO: can we have non-utf8 tags? */ rp_val = bson_iter_utf8 (&rp_iter, &rp_len); if (bson_iter_init_find (&sd_iter, &descriptions[i]->tags, bson_iter_key (&rp_iter))) { /* If the server description has that key */ sd_val = bson_iter_utf8 (&sd_iter, &sd_len); if (! (sd_len == rp_len && (0 == memcmp(rp_val, sd_val, rp_len)))) { /* If the key value doesn't match, no match */ sd_matched[i] = false; found--; } } else { /* If the server description doesn't have that key, no match */ sd_matched[i] = false; found--; break; } } } if (found) { for (i = 0; i < description_len; i++) { if (! sd_matched[i]) { descriptions[i] = NULL; } } rval = found; goto CLEANUP; } } for (i = 0; i < description_len; i++) { if (! sd_matched[i]) { descriptions[i] = NULL; } } CLEANUP: bson_free (sd_matched); return rval; } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-server-description.h0000664000175000017500000000233512673034026025102 0ustar jmikolajmikola/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_SERVER_DESCRIPTION_H #define MONGOC_SERVER_DESCRIPTION_H #include #include "mongoc-array-private.h" #include "mongoc-read-prefs.h" #include "mongoc-host-list.h" typedef struct _mongoc_server_description_t mongoc_server_description_t; void mongoc_server_description_destroy (mongoc_server_description_t *description); mongoc_server_description_t * mongoc_server_description_new_copy (const mongoc_server_description_t *description); uint32_t mongoc_server_description_id (mongoc_server_description_t *description); mongoc_host_list_t * mongoc_server_description_host (mongoc_server_description_t *description); #endif mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-server-stream-private.h0000664000175000017500000000346112673034026025523 0ustar jmikolajmikola/* * Copyright 2015 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_SERVER_STREAM_H #define MONGOC_SERVER_STREAM_H #include "mongoc-config.h" #if !defined (MONGOC_I_AM_A_DRIVER) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #include #include "mongoc-topology-description-private.h" #include "mongoc-server-description-private.h" #include "mongoc-stream.h" BSON_BEGIN_DECLS typedef struct _mongoc_server_stream_t { mongoc_topology_description_type_t topology_type; mongoc_server_description_t *sd; /* owned */ mongoc_stream_t *stream; /* borrowed */ } mongoc_server_stream_t; mongoc_server_stream_t * mongoc_server_stream_new (mongoc_topology_description_type_t topology_type, mongoc_server_description_t *sd, mongoc_stream_t *stream); int32_t mongoc_server_stream_max_bson_obj_size (mongoc_server_stream_t *server_stream); int32_t mongoc_server_stream_max_msg_size (mongoc_server_stream_t *server_stream); int32_t mongoc_server_stream_max_write_batch_size (mongoc_server_stream_t *server_stream); void mongoc_server_stream_cleanup (mongoc_server_stream_t *server_stream); BSON_END_DECLS #endif /* MONGOC_SERVER_STREAM_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-server-stream.c0000664000175000017500000000572412673034026024052 0ustar jmikolajmikola/* * Copyright 2015 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "mongoc-cluster-private.h" #include "mongoc-server-stream-private.h" #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "server-stream" #define COALESCE(x, y) ((x == 0) ? (y) : (x)) mongoc_server_stream_t * mongoc_server_stream_new (mongoc_topology_description_type_t topology_type, mongoc_server_description_t *sd, mongoc_stream_t *stream) { mongoc_server_stream_t *server_stream; BSON_ASSERT (sd); BSON_ASSERT (stream); server_stream = bson_malloc (sizeof (mongoc_server_stream_t)); server_stream->topology_type = topology_type; server_stream->sd = sd; /* becomes owned */ server_stream->stream = stream; /* merely borrowed */ return server_stream; } void mongoc_server_stream_cleanup (mongoc_server_stream_t *server_stream) { if (server_stream) { mongoc_server_description_destroy (server_stream->sd); bson_free (server_stream); } } /* *-------------------------------------------------------------------------- * * mongoc_server_stream_max_bson_obj_size -- * * Return the max bson object size for the given server stream. * *-------------------------------------------------------------------------- */ int32_t mongoc_server_stream_max_bson_obj_size (mongoc_server_stream_t *server_stream) { return COALESCE (server_stream->sd->max_bson_obj_size, MONGOC_DEFAULT_BSON_OBJ_SIZE); } /* *-------------------------------------------------------------------------- * * mongoc_server_stream_max_msg_size -- * * Return the max message size for the given server stream. * *-------------------------------------------------------------------------- */ int32_t mongoc_server_stream_max_msg_size (mongoc_server_stream_t *server_stream) { return COALESCE (server_stream->sd->max_msg_size, MONGOC_DEFAULT_MAX_MSG_SIZE); } /* *-------------------------------------------------------------------------- * * mongoc_server_stream_max_write_batch_size -- * * Return the max write batch size for the given server stream. * *-------------------------------------------------------------------------- */ int32_t mongoc_server_stream_max_write_batch_size (mongoc_server_stream_t *server_stream) { return COALESCE (server_stream->sd->max_write_batch_size, MONGOC_DEFAULT_WRITE_BATCH_SIZE); }mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-set-private.h0000664000175000017500000000533012673034026023514 0ustar jmikolajmikola/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_SET_PRIVATE_H #define MONGOC_SET_PRIVATE_H #if !defined (MONGOC_I_AM_A_DRIVER) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #include BSON_BEGIN_DECLS typedef void (*mongoc_set_item_dtor)(void *item, void *ctx); /* return true to continue iteration, false to stop */ typedef bool (*mongoc_set_for_each_cb_t)(void *item, void *ctx); typedef struct { uint32_t id; void *item; } mongoc_set_item_t; typedef struct { mongoc_set_item_t *items; size_t items_len; size_t items_allocated; mongoc_set_item_dtor dtor; void *dtor_ctx; } mongoc_set_t; mongoc_set_t * mongoc_set_new (size_t nitems, mongoc_set_item_dtor dtor, void *dtor_ctx); void mongoc_set_add (mongoc_set_t *set, uint32_t id, void *item); void mongoc_set_rm (mongoc_set_t *set, uint32_t id); void * mongoc_set_get (mongoc_set_t *set, uint32_t id); void * mongoc_set_get_item (mongoc_set_t *set, int idx); void mongoc_set_destroy (mongoc_set_t *set); /* loops over the set safe-ish. * * Caveats: * - you can add items at any iteration * - if you remove elements other than the one you're currently looking at, * you may see it later in the iteration */ void mongoc_set_for_each (mongoc_set_t *set, mongoc_set_for_each_cb_t cb, void *ctx); /* first item in set for which "cb" returns true */ void * mongoc_set_find_item (mongoc_set_t *set, mongoc_set_for_each_cb_t cb, void *ctx); /* id of first item in set for which "cb" returns true, or 0. */ uint32_t mongoc_set_find_id (mongoc_set_t *set, mongoc_set_for_each_cb_t cb, void *ctx); BSON_END_DECLS #endif /* MONGOC_SET_PRIVATE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-set.c0000664000175000017500000001136412673034026022043 0ustar jmikolajmikola/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include "mongoc-set-private.h" #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "set" mongoc_set_t * mongoc_set_new (size_t nitems, mongoc_set_item_dtor dtor, void *dtor_ctx) { mongoc_set_t *set = (mongoc_set_t *)bson_malloc (sizeof (*set)); set->items_allocated = nitems; set->items = (mongoc_set_item_t *)bson_malloc (sizeof (*set->items) * set->items_allocated); set->items_len = 0; set->dtor = dtor; set->dtor_ctx = dtor_ctx; return set; } static int mongoc_set_id_cmp (const void *a_, const void *b_) { mongoc_set_item_t *a = (mongoc_set_item_t *)a_; mongoc_set_item_t *b = (mongoc_set_item_t *)b_; if (a->id == b->id) { return 0; } return a->id < b->id ? -1 : 1; } void mongoc_set_add (mongoc_set_t *set, uint32_t id, void *item) { if (set->items_len >= set->items_allocated) { set->items_allocated *= 2; set->items = (mongoc_set_item_t *)bson_realloc (set->items, sizeof (*set->items) * set->items_allocated); } set->items[set->items_len].id = id; set->items[set->items_len].item = item; set->items_len++; if (set->items_len > 1 && set->items[set->items_len - 2].id > id) { qsort (set->items, set->items_len, sizeof (*set->items), mongoc_set_id_cmp); } } void mongoc_set_rm (mongoc_set_t *set, uint32_t id) { mongoc_set_item_t *ptr; mongoc_set_item_t key; int i; key.id = id; ptr = (mongoc_set_item_t *)bsearch (&key, set->items, set->items_len, sizeof (key), mongoc_set_id_cmp); if (ptr) { set->dtor(ptr->item, set->dtor_ctx); i = ptr - set->items; if (i != set->items_len - 1) { memmove (set->items + i, set->items + i + 1, (set->items_len - (i + 1)) * sizeof (key)); } set->items_len--; } } void * mongoc_set_get (mongoc_set_t *set, uint32_t id) { mongoc_set_item_t *ptr; mongoc_set_item_t key; key.id = id; ptr = (mongoc_set_item_t *)bsearch (&key, set->items, set->items_len, sizeof (key), mongoc_set_id_cmp); return ptr ? ptr->item : NULL; } void * mongoc_set_get_item (mongoc_set_t *set, int idx) { BSON_ASSERT (set); BSON_ASSERT (idx < set->items_len); return set->items[idx].item; } void mongoc_set_destroy (mongoc_set_t *set) { int i; for (i = 0; i < set->items_len; i++) { set->dtor(set->items[i].item, set->dtor_ctx); } bson_free (set->items); bson_free (set); } void mongoc_set_for_each (mongoc_set_t *set, mongoc_set_for_each_cb_t cb, void *ctx) { size_t i; mongoc_set_item_t *old_set; size_t items_len; items_len = set->items_len; old_set = (mongoc_set_item_t *)bson_malloc (sizeof (*old_set) * items_len); memcpy (old_set, set->items, sizeof (*old_set) * items_len); for (i = 0; i < items_len; i++) { if (!cb (old_set[i].item, ctx)) { break; } } bson_free (old_set); } static mongoc_set_item_t * _mongoc_set_find (mongoc_set_t *set, mongoc_set_for_each_cb_t cb, void *ctx) { size_t i; size_t items_len; mongoc_set_item_t *item; items_len = set->items_len; for (i = 0; i < items_len; i++) { item = &set->items[i]; if (cb (item->item, ctx)) { return item; } } return NULL; } void * mongoc_set_find_item (mongoc_set_t *set, mongoc_set_for_each_cb_t cb, void *ctx) { mongoc_set_item_t *item; if ((item = _mongoc_set_find (set, cb, ctx))) { return item->item; } return NULL; } uint32_t mongoc_set_find_id (mongoc_set_t *set, mongoc_set_for_each_cb_t cb, void *ctx) { mongoc_set_item_t *item; if ((item = _mongoc_set_find (set, cb, ctx))) { return item->id; } return 0; } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-socket-private.h0000664000175000017500000000225412673034026024213 0ustar jmikolajmikola/* * Copyright 2015 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_SOCKET_PRIVATE_H #define MONGOC_SOCKET_PRIVATE_H #if !defined (MONGOC_INSIDE) && !defined (MONGOC_COMPILATION) # error "Only can be included directly." #endif #include "mongoc-socket.h" BSON_BEGIN_DECLS struct _mongoc_socket_t { #ifdef _WIN32 SOCKET sd; #else int sd; #endif int errno_; int domain; }; mongoc_socket_t *mongoc_socket_accept_ex (mongoc_socket_t *sock, int64_t expire_at, uint16_t *port); BSON_END_DECLS #endif /* MONGOC_SOCKET_PRIVATE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-socket.c0000664000175000017500000007042212673034026022540 0ustar jmikolajmikola/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include "mongoc-counters-private.h" #include "mongoc-errno-private.h" #include "mongoc-socket-private.h" #include "mongoc-host-list.h" #include "mongoc-socket-private.h" #include "mongoc-trace.h" #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "socket" #define OPERATION_EXPIRED(expire_at) \ ((expire_at >= 0) && (expire_at < (bson_get_monotonic_time()))) /* *-------------------------------------------------------------------------- * * _mongoc_socket_setnonblock -- * * A helper to set a socket in nonblocking mode. * * Returns: * true if successful; otherwise false. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static bool #ifdef _WIN32 _mongoc_socket_setnonblock (SOCKET sd) #else _mongoc_socket_setnonblock (int sd) #endif { #ifdef _WIN32 u_long io_mode = 1; return (NO_ERROR == ioctlsocket (sd, FIONBIO, &io_mode)); #else int flags; flags = fcntl (sd, F_GETFL, sd); return (-1 != fcntl (sd, F_SETFL, (flags | O_NONBLOCK))); #endif } /* *-------------------------------------------------------------------------- * * _mongoc_socket_wait -- * * A single socket poll helper. * * @events: in most cases should be POLLIN or POLLOUT. * * @expire_at should be an absolute time at which to expire using * the monotonic clock (bson_get_monotonic_time(), which is in * microseconds). Or zero to not block at all. Or -1 to block * forever. * * Returns: * true if an event matched. otherwise false. * a timeout will return false. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static bool #ifdef _WIN32 _mongoc_socket_wait (SOCKET sd, /* IN */ #else _mongoc_socket_wait (int sd, /* IN */ #endif int events, /* IN */ int64_t expire_at) /* IN */ { #ifdef _WIN32 WSAPOLLFD pfd; #else struct pollfd pfd; #endif int ret; int timeout; int64_t now; ENTRY; BSON_ASSERT (events); pfd.fd = sd; #ifdef _WIN32 pfd.events = events; #else pfd.events = events | POLLERR | POLLHUP; #endif pfd.revents = 0; now = bson_get_monotonic_time(); for (;;) { if (expire_at < 0) { timeout = -1; } else if (expire_at == 0) { timeout = 0; } else { timeout = (int)((expire_at - now) / 1000L); if (timeout < 0) { timeout = 0; } } #ifdef _WIN32 ret = WSAPoll (&pfd, 1, timeout); if (ret == SOCKET_ERROR) { errno = WSAGetLastError(); ret = -1; } #else ret = poll (&pfd, 1, timeout); #endif if (ret > 0) { /* Something happened, so return that */ #ifdef _WIN32 RETURN (0 != (pfd.revents & (events | POLLHUP | POLLERR))); #else RETURN (0 != (pfd.revents & events)); #endif } else if (ret < 0) { /* poll itself failed */ TRACE("errno is: %d", errno); if (MONGOC_ERRNO_IS_AGAIN(errno)) { now = bson_get_monotonic_time(); if (expire_at < now) { RETURN (false); } else { continue; } } else { /* poll failed for some non-transient reason */ RETURN (false); } } else { /* poll timed out */ RETURN (false); } } } /* *-------------------------------------------------------------------------- * * _mongoc_socket_poll -- * * A multi-socket poll helper. * * @events: in most cases should be POLLIN or POLLOUT. * * @expire_at should be an absolute time at which to expire using * the monotonic clock (bson_get_monotonic_time(), which is in * microseconds). Or zero to not block at all. Or -1 to block * forever. * * Returns: * true if an event matched. otherwise false. * a timeout will return false. * * Side effects: * None. * *-------------------------------------------------------------------------- */ ssize_t mongoc_socket_poll (mongoc_socket_poll_t *sds, /* IN */ size_t nsds, /* IN */ int32_t timeout) /* IN */ { #ifdef _WIN32 WSAPOLLFD *pfds; #else struct pollfd *pfds; #endif int ret; int i; ENTRY; BSON_ASSERT (sds); #ifdef _WIN32 pfds = (WSAPOLLFD *)bson_malloc(sizeof(*pfds) * nsds); #else pfds = (struct pollfd *)bson_malloc(sizeof(*pfds) * nsds); #endif for (i = 0; i < nsds; i++) { pfds[i].fd = sds[i].socket->sd; #ifdef _WIN32 pfds[i].events = sds[i].events; #else pfds[i].events = sds[i].events | POLLERR | POLLHUP; #endif pfds[i].revents = 0; } #ifdef _WIN32 ret = WSAPoll (pfds, nsds, timeout); if (ret == SOCKET_ERROR) { MONGOC_WARNING ("WSAGetLastError(): %d", WSAGetLastError ()); ret = -1; } #else ret = poll (pfds, nsds, timeout); #endif for (i = 0; i < nsds; i++) { sds[i].revents = pfds[i].revents; } bson_free(pfds); return ret; } static bool #ifdef _WIN32 _mongoc_socket_setnodelay (SOCKET sd) /* IN */ #else _mongoc_socket_setnodelay (int sd) /* IN */ #endif { #ifdef _WIN32 BOOL optval = 1; #else int optval = 1; #endif int ret; ENTRY; errno = 0; ret = setsockopt (sd, IPPROTO_TCP, TCP_NODELAY, (char *)&optval, sizeof optval); #ifdef _WIN32 if (ret == SOCKET_ERROR) { MONGOC_WARNING ("WSAGetLastError(): %d", (int)WSAGetLastError ()); } #endif RETURN (ret == 0); } /* *-------------------------------------------------------------------------- * * mongoc_socket_errno -- * * Returns the last error on the socket. * * Returns: * An integer errno, or 0 on no error. * * Side effects: * None. * *-------------------------------------------------------------------------- */ int mongoc_socket_errno (mongoc_socket_t *sock) /* IN */ { BSON_ASSERT (sock); TRACE("Current errno: %d", sock->errno_); return sock->errno_; } /* *-------------------------------------------------------------------------- * * _mongoc_socket_capture_errno -- * * Save the errno state for contextual use. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static void _mongoc_socket_capture_errno (mongoc_socket_t *sock) /* IN */ { #ifdef _WIN32 errno = sock->errno_ = WSAGetLastError (); #else sock->errno_ = errno; #endif TRACE("setting errno: %d", sock->errno_); } /* *-------------------------------------------------------------------------- * * _mongoc_socket_errno_is_again -- * * Check to see if we should attempt to make further progress * based on the error of the last operation. * * Returns: * true if we should try again. otherwise false. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static bool _mongoc_socket_errno_is_again (mongoc_socket_t *sock) /* IN */ { TRACE("errno is: %d", sock->errno_); return MONGOC_ERRNO_IS_AGAIN (sock->errno_); } /* *-------------------------------------------------------------------------- * * mongoc_socket_accept -- * * Wrapper for BSD socket accept(). Handles portability between * BSD sockets and WinSock2 on Windows Vista and newer. * * Returns: * NULL upon failure to accept or timeout. * A newly allocated mongoc_socket_t on success. * * Side effects: * *port contains the client port number. * *-------------------------------------------------------------------------- */ mongoc_socket_t * mongoc_socket_accept (mongoc_socket_t *sock, /* IN */ int64_t expire_at) /* IN */ { return mongoc_socket_accept_ex (sock, expire_at, NULL); } /* *-------------------------------------------------------------------------- * * mongoc_socket_accept_ex -- * * Private synonym for mongoc_socket_accept, returning client port. * * Returns: * NULL upon failure to accept or timeout. * A newly allocated mongoc_socket_t on success. * * Side effects: * *port contains the client port number. * *-------------------------------------------------------------------------- */ mongoc_socket_t * mongoc_socket_accept_ex (mongoc_socket_t *sock, /* IN */ int64_t expire_at, /* IN */ uint16_t *port) /* OUT */ { mongoc_socket_t *client; struct sockaddr_in addr; socklen_t addrlen = sizeof addr; bool try_again = false; bool failed = false; #ifdef _WIN32 SOCKET sd; #else int sd; #endif ENTRY; BSON_ASSERT (sock); again: errno = 0; sd = accept (sock->sd, (struct sockaddr *) &addr, &addrlen); _mongoc_socket_capture_errno (sock); #ifdef _WIN32 failed = (sd == INVALID_SOCKET); #else failed = (sd == -1); #endif try_again = (failed && _mongoc_socket_errno_is_again (sock)); if (failed && try_again) { if (_mongoc_socket_wait (sock->sd, POLLIN, expire_at)) { GOTO (again); } RETURN (NULL); } else if (failed) { RETURN (NULL); } else if (!_mongoc_socket_setnonblock (sd)) { #ifdef _WIN32 closesocket (sd); #else close (sd); #endif RETURN (NULL); } client = (mongoc_socket_t *)bson_malloc0 (sizeof *client); client->sd = sd; if (port) { *port = ntohs (addr.sin_port); } if (!_mongoc_socket_setnodelay (client->sd)) { MONGOC_WARNING ("Failed to enable TCP_NODELAY."); } RETURN (client); } /* *-------------------------------------------------------------------------- * * mongo_socket_bind -- * * A wrapper around bind(). * * Returns: * 0 on success, -1 on failure and errno is set. * * Side effects: * None. * *-------------------------------------------------------------------------- */ int mongoc_socket_bind (mongoc_socket_t *sock, /* IN */ const struct sockaddr *addr, /* IN */ socklen_t addrlen) /* IN */ { int ret; ENTRY; BSON_ASSERT (sock); BSON_ASSERT (addr); BSON_ASSERT (addrlen); ret = bind (sock->sd, addr, addrlen); _mongoc_socket_capture_errno (sock); RETURN (ret); } /* *-------------------------------------------------------------------------- * * mongoc_socket_close -- * * Closes the underlying socket. * * In general, you probably don't want to handle the result from * this. That could cause race conditions in the case of preemtion * during system call (EINTR). * * Returns: * 0 on success, -1 on failure. * * Side effects: * None. * *-------------------------------------------------------------------------- */ int mongoc_socket_close (mongoc_socket_t *sock) /* IN */ { ENTRY; BSON_ASSERT (sock); #ifdef _WIN32 if (sock->sd != INVALID_SOCKET) { shutdown (sock->sd, SD_BOTH); if (0 == closesocket (sock->sd)) { sock->sd = INVALID_SOCKET; } else { _mongoc_socket_capture_errno (sock); RETURN(-1); } } RETURN(0); #else if (sock->sd != -1) { shutdown (sock->sd, SHUT_RDWR); if (0 == close (sock->sd)) { sock->sd = -1; } else { _mongoc_socket_capture_errno (sock); RETURN(-1); } } RETURN(0); #endif } /* *-------------------------------------------------------------------------- * * mongoc_socket_connect -- * * Performs a socket connection but will fail if @expire_at is * reached by the monotonic clock. * * Returns: * 0 if success, otherwise -1 and errno is set. * * Side effects: * None. * *-------------------------------------------------------------------------- */ int mongoc_socket_connect (mongoc_socket_t *sock, /* IN */ const struct sockaddr *addr, /* IN */ socklen_t addrlen, /* IN */ int64_t expire_at) /* IN */ { bool try_again = false; bool failed = false; int ret; int optval; socklen_t optlen = sizeof optval; ENTRY; BSON_ASSERT (sock); BSON_ASSERT (addr); BSON_ASSERT (addrlen); ret = connect (sock->sd, addr, addrlen); #ifdef _WIN32 if (ret == SOCKET_ERROR) { #else if (ret == -1) { #endif _mongoc_socket_capture_errno (sock); failed = true; try_again = _mongoc_socket_errno_is_again (sock); } if (failed && try_again) { if (_mongoc_socket_wait (sock->sd, POLLOUT, expire_at)) { optval = -1; ret = getsockopt (sock->sd, SOL_SOCKET, SO_ERROR, (char *)&optval, &optlen); if ((ret == 0) && (optval == 0)) { RETURN (0); } else { errno = sock->errno_ = optval; } } RETURN (-1); } else if (failed) { RETURN (-1); } else { RETURN (0); } } /* *-------------------------------------------------------------------------- * * mongoc_socket_destroy -- * * Cleanup after a mongoc_socket_t structure, possibly closing * underlying sockets. * * Returns: * None. * * Side effects: * @sock is freed and should be considered invalid. * *-------------------------------------------------------------------------- */ void mongoc_socket_destroy (mongoc_socket_t *sock) /* IN */ { if (sock) { mongoc_socket_close (sock); bson_free (sock); } } /* *-------------------------------------------------------------------------- * * mongoc_socket_listen -- * * Listen for incoming requests with a backlog up to @backlog. * * If @backlog is zero, a sensible default will be chosen. * * Returns: * true if successful; otherwise false. * * Side effects: * None. * *-------------------------------------------------------------------------- */ int mongoc_socket_listen (mongoc_socket_t *sock, /* IN */ unsigned int backlog) /* IN */ { int ret; ENTRY; BSON_ASSERT (sock); if (backlog == 0) { backlog = 10; } ret = listen (sock->sd, backlog); _mongoc_socket_capture_errno (sock); RETURN (ret); } /* *-------------------------------------------------------------------------- * * mongoc_socket_new -- * * Create a new socket. * * Free the result mongoc_socket_destroy(). * * Returns: * A newly allocated socket. * NULL on failure. * * Side effects: * None. * *-------------------------------------------------------------------------- */ mongoc_socket_t * mongoc_socket_new (int domain, /* IN */ int type, /* IN */ int protocol) /* IN */ { mongoc_socket_t *sock; #ifdef _WIN32 SOCKET sd; #else int sd; #endif ENTRY; sd = socket (domain, type, protocol); #ifdef _WIN32 if (sd == INVALID_SOCKET) { #else if (sd == -1) { #endif RETURN (NULL); } if (!_mongoc_socket_setnonblock (sd)) { GOTO (fail); } if (domain != AF_UNIX && !_mongoc_socket_setnodelay (sd)) { MONGOC_WARNING ("Failed to enable TCP_NODELAY."); } sock = (mongoc_socket_t *)bson_malloc0 (sizeof *sock); sock->sd = sd; sock->domain = domain; RETURN (sock); fail: #ifdef _WIN32 closesocket (sd); #else close (sd); #endif RETURN (NULL); } /* *-------------------------------------------------------------------------- * * mongoc_socket_recv -- * * A portable wrapper around recv() that also respects an absolute * timeout. * * @expire_at is 0 for no blocking, -1 for infinite blocking, * or a time using the monotonic clock to expire. Calculate this * using bson_get_monotonic_time() + N_MICROSECONDS. * * Returns: * The number of bytes received on success. * 0 on end of stream. * -1 on failure. * * Side effects: * @buf will be read into. * *-------------------------------------------------------------------------- */ ssize_t mongoc_socket_recv (mongoc_socket_t *sock, /* IN */ void *buf, /* OUT */ size_t buflen, /* IN */ int flags, /* IN */ int64_t expire_at) /* IN */ { ssize_t ret = 0; bool failed = false; ENTRY; BSON_ASSERT (sock); BSON_ASSERT (buf); BSON_ASSERT (buflen); again: sock->errno_ = 0; #ifdef _WIN32 ret = recv (sock->sd, (char *)buf, (int)buflen, flags); failed = (ret == SOCKET_ERROR); #else ret = recv (sock->sd, buf, buflen, flags); failed = (ret == -1); #endif if (failed) { _mongoc_socket_capture_errno (sock); if (_mongoc_socket_errno_is_again (sock) && _mongoc_socket_wait (sock->sd, POLLIN, expire_at)) { GOTO (again); } } if (failed) { RETURN (-1); } mongoc_counter_streams_ingress_add (ret); RETURN (ret); } /* *-------------------------------------------------------------------------- * * mongoc_socket_setsockopt -- * * A wrapper around setsockopt(). * * Returns: * 0 on success, -1 on failure. * * Side effects: * None. * *-------------------------------------------------------------------------- */ int mongoc_socket_setsockopt (mongoc_socket_t *sock, /* IN */ int level, /* IN */ int optname, /* IN */ const void *optval, /* IN */ socklen_t optlen) /* IN */ { int ret; ENTRY; BSON_ASSERT (sock); ret = setsockopt (sock->sd, level, optname, optval, optlen); _mongoc_socket_capture_errno (sock); RETURN (ret); } /* *-------------------------------------------------------------------------- * * mongoc_socket_send -- * * A simplified wrapper around mongoc_socket_sendv(). * * @expire_at is 0 for no blocking, -1 for infinite blocking, * or a time using the monotonic clock to expire. Calculate this * using bson_get_monotonic_time() + N_MICROSECONDS. * * Returns: * -1 on failure. number of bytes written on success. * * Side effects: * None. * *-------------------------------------------------------------------------- */ ssize_t mongoc_socket_send (mongoc_socket_t *sock, /* IN */ const void *buf, /* IN */ size_t buflen, /* IN */ int64_t expire_at) /* IN */ { mongoc_iovec_t iov; BSON_ASSERT (sock); BSON_ASSERT (buf); BSON_ASSERT (buflen); iov.iov_base = (void *)buf; iov.iov_len = buflen; return mongoc_socket_sendv (sock, &iov, 1, expire_at); } /* *-------------------------------------------------------------------------- * * _mongoc_socket_try_sendv_slow -- * * A slow variant of _mongoc_socket_try_sendv() that sends each * iovec entry one by one. This can happen if we hit EMSGSIZE * with sendmsg() on various POSIX systems or WSASend()+WSAEMSGSIZE * on Windows. * * Returns: * the number of bytes sent or -1 and errno is set. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static ssize_t _mongoc_socket_try_sendv_slow (mongoc_socket_t *sock, /* IN */ mongoc_iovec_t *iov, /* IN */ size_t iovcnt) /* IN */ { ssize_t ret = 0; size_t i; ssize_t wrote; ENTRY; BSON_ASSERT (sock); BSON_ASSERT (iov); BSON_ASSERT (iovcnt); for (i = 0; i < iovcnt; i++) { wrote = send (sock->sd, iov [i].iov_base, iov [i].iov_len, 0); #ifdef _WIN32 if (wrote == SOCKET_ERROR) { #else if (wrote == -1) { #endif _mongoc_socket_capture_errno (sock); if (!_mongoc_socket_errno_is_again (sock)) { RETURN (-1); } RETURN (ret ? ret : -1); } ret += wrote; if (wrote != iov [i].iov_len) { RETURN (ret); } } RETURN (ret); } /* *-------------------------------------------------------------------------- * * _mongoc_socket_try_sendv -- * * Helper used by mongoc_socket_sendv() to try to write as many * bytes to the underlying socket until the socket buffer is full. * * This is performed in a non-blocking fashion. * * Returns: * -1 on failure. the number of bytes written on success. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static ssize_t _mongoc_socket_try_sendv (mongoc_socket_t *sock, /* IN */ mongoc_iovec_t *iov, /* IN */ size_t iovcnt) /* IN */ { #ifdef _WIN32 DWORD dwNumberofBytesSent = 0; int ret; #else struct msghdr msg; ssize_t ret; #endif ENTRY; BSON_ASSERT (sock); BSON_ASSERT (iov); BSON_ASSERT (iovcnt); DUMP_IOVEC (sendbuf, iov, iovcnt); #ifdef _WIN32 ret = WSASend (sock->sd, (LPWSABUF)iov, iovcnt, &dwNumberofBytesSent, 0, NULL, NULL); TRACE("WSASend sent: %ld (out of: %ld), ret: %d", dwNumberofBytesSent, iov->iov_len, ret); #else memset (&msg, 0, sizeof msg); msg.msg_iov = iov; msg.msg_iovlen = (int) iovcnt; ret = sendmsg (sock->sd, &msg, # ifdef MSG_NOSIGNAL MSG_NOSIGNAL); # else 0); # endif TRACE("Send %ld out of %ld bytes", ret, iov->iov_len); #endif #ifdef _WIN32 if (ret == SOCKET_ERROR) { #else if (ret == -1) { #endif _mongoc_socket_capture_errno (sock); /* * Check to see if we have sent an iovec too large for sendmsg to * complete. If so, we need to fallback to the slow path of multiple * send() commands. */ #ifdef _WIN32 if (mongoc_socket_errno (sock) == WSAEMSGSIZE) { #else if (mongoc_socket_errno (sock) == EMSGSIZE) { #endif RETURN(_mongoc_socket_try_sendv_slow (sock, iov, iovcnt)); } RETURN (-1); } #ifdef _WIN32 RETURN (dwNumberofBytesSent); #else RETURN (ret); #endif } /* *-------------------------------------------------------------------------- * * mongoc_socket_sendv -- * * A wrapper around using sendmsg() to send an iovec. * This also deals with the structure differences between * WSABUF and struct iovec. * * @expire_at is 0 for no blocking, -1 for infinite blocking, * or a time using the monotonic clock to expire. Calculate this * using bson_get_monotonic_time() + N_MICROSECONDS. * * Returns: * -1 on failure. * the number of bytes written on success. * * Side effects: * None. * *-------------------------------------------------------------------------- */ ssize_t mongoc_socket_sendv (mongoc_socket_t *sock, /* IN */ mongoc_iovec_t *in_iov, /* IN */ size_t iovcnt, /* IN */ int64_t expire_at) /* IN */ { ssize_t ret = 0; ssize_t sent; size_t cur = 0; mongoc_iovec_t *iov; ENTRY; BSON_ASSERT (sock); BSON_ASSERT (in_iov); BSON_ASSERT (iovcnt); iov = bson_malloc(sizeof(*iov) * iovcnt); memcpy(iov, in_iov, sizeof(*iov) * iovcnt); for (;;) { sent = _mongoc_socket_try_sendv (sock, &iov [cur], iovcnt - cur); TRACE("Sent %ld (of %ld) out of iovcnt=%ld", sent, iov[cur].iov_len, iovcnt); /* * If we failed with anything other than EAGAIN or EWOULDBLOCK, * we should fail immediately as there is another issue with the * underlying socket. */ if (sent == -1) { if (!_mongoc_socket_errno_is_again (sock)) { ret = -1; GOTO(CLEANUP); } } /* * Update internal stream counters. */ if (sent > 0) { ret += sent; mongoc_counter_streams_egress_add (sent); /* * Subtract the sent amount from what we still need to send. */ while ((cur < iovcnt) && (sent >= (ssize_t)iov [cur].iov_len)) { TRACE("still got bytes left: sent -= iov_len: %ld -= %ld", sent, iov[cur+1].iov_len); sent -= iov [cur++].iov_len; } /* * Check if that made us finish all of the iovecs. If so, we are done * sending data over the socket. */ if (cur == iovcnt) { TRACE("%s", "Finished the iovecs"); break; } /* * Increment the current iovec buffer to its proper offset and adjust * the number of bytes to write. */ TRACE("Seeked io_base+%ld", sent); TRACE("Subtracting iov_len -= sent; %ld -= %ld", iov[cur].iov_len, sent); iov [cur].iov_base = ((char *)iov [cur].iov_base) + sent; iov [cur].iov_len -= sent; TRACE("iov_len remaining %ld", iov[cur].iov_len); BSON_ASSERT (iovcnt - cur); BSON_ASSERT (iov [cur].iov_len); } else if (OPERATION_EXPIRED (expire_at)) { GOTO(CLEANUP); } /* * Block on poll() until our desired condition is met. */ if (!_mongoc_socket_wait (sock->sd, POLLOUT, expire_at)) { GOTO(CLEANUP); } } CLEANUP: bson_free(iov); RETURN (ret); } int mongoc_socket_getsockname (mongoc_socket_t *sock, /* IN */ struct sockaddr *addr, /* OUT */ socklen_t *addrlen) /* INOUT */ { int ret; ENTRY; BSON_ASSERT (sock); ret = getsockname (sock->sd, addr, addrlen); _mongoc_socket_capture_errno (sock); RETURN (ret); } char * mongoc_socket_getnameinfo (mongoc_socket_t *sock) /* IN */ { struct sockaddr addr; socklen_t len = sizeof addr; char *ret; char host [BSON_HOST_NAME_MAX + 1]; ENTRY; BSON_ASSERT (sock); if ((0 == getpeername (sock->sd, &addr, &len)) && (0 == getnameinfo (&addr, len, host, sizeof host, NULL, 0, 0))) { ret = bson_strdup (host); RETURN (ret); } RETURN (NULL); } bool mongoc_socket_check_closed (mongoc_socket_t *sock) /* IN */ { bool closed = false; char buf [1]; ssize_t r; if (_mongoc_socket_wait (sock->sd, POLLIN, 0)) { sock->errno_ = 0; r = recv (sock->sd, buf, 1, MSG_PEEK); if (r < 0) { _mongoc_socket_capture_errno (sock); } if (r < 1) { closed = true; } } return closed; } /* * *-------------------------------------------------------------------------- * * mongoc_socket_inet_ntop -- * * Convert the ip from addrinfo into a c string. * * Returns: * The value is returned into 'buffer'. The memory has to be allocated * by the caller * * Side effects: * None. * *-------------------------------------------------------------------------- */ void mongoc_socket_inet_ntop (struct addrinfo *rp, /* IN */ char *buf, /* INOUT */ size_t buflen) /* IN */ { void *ptr; char tmp[256]; switch (rp->ai_family) { case AF_INET: ptr = &((struct sockaddr_in *)rp->ai_addr)->sin_addr; inet_ntop (rp->ai_family, ptr, tmp, sizeof (tmp)); bson_snprintf (buf, buflen, "ipv4 %s", tmp); break; case AF_INET6: ptr = &((struct sockaddr_in6 *)rp->ai_addr)->sin6_addr; inet_ntop (rp->ai_family, ptr, tmp, sizeof (tmp)); bson_snprintf (buf, buflen, "ipv6 %s", tmp); break; default: bson_snprintf (buf, buflen, "unknown ip %d", rp->ai_family); break; } } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-socket.h0000664000175000017500000001117512673034026022545 0ustar jmikolajmikola/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_SOCKET_H #define MONGOC_SOCKET_H #if !defined (MONGOC_INSIDE) && !defined (MONGOC_COMPILATION) # error "Only can be included directly." #endif #include #ifdef _WIN32 # include # include #else # include # include # include # include # include # include # include # include # include #endif #include "mongoc-iovec.h" BSON_BEGIN_DECLS typedef struct _mongoc_socket_t mongoc_socket_t; typedef struct { mongoc_socket_t *socket; int events; int revents; } mongoc_socket_poll_t; mongoc_socket_t *mongoc_socket_accept (mongoc_socket_t *sock, int64_t expire_at); int mongoc_socket_bind (mongoc_socket_t *sock, const struct sockaddr *addr, socklen_t addrlen); int mongoc_socket_close (mongoc_socket_t *socket); int mongoc_socket_connect (mongoc_socket_t *sock, const struct sockaddr *addr, socklen_t addrlen, int64_t expire_at); char *mongoc_socket_getnameinfo(mongoc_socket_t *sock); void mongoc_socket_destroy (mongoc_socket_t *sock); int mongoc_socket_errno (mongoc_socket_t *sock); int mongoc_socket_getsockname(mongoc_socket_t *sock, struct sockaddr *addr, socklen_t *addrlen); int mongoc_socket_listen (mongoc_socket_t *sock, unsigned int backlog); mongoc_socket_t *mongoc_socket_new (int domain, int type, int protocol); ssize_t mongoc_socket_recv (mongoc_socket_t *sock, void *buf, size_t buflen, int flags, int64_t expire_at); int mongoc_socket_setsockopt (mongoc_socket_t *sock, int level, int optname, const void *optval, socklen_t optlen); ssize_t mongoc_socket_send (mongoc_socket_t *sock, const void *buf, size_t buflen, int64_t expire_at); ssize_t mongoc_socket_sendv (mongoc_socket_t *sock, mongoc_iovec_t *iov, size_t iovcnt, int64_t expire_at); bool mongoc_socket_check_closed (mongoc_socket_t *sock); void mongoc_socket_inet_ntop (struct addrinfo *rp, char *buf, size_t buflen); ssize_t mongoc_socket_poll (mongoc_socket_poll_t *sds, size_t nsds, int32_t timeout); BSON_END_DECLS #endif /* MONGOC_SOCKET_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-ssl-private.h0000664000175000017500000000256412673034026023530 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_SSL_PRIVATE_H #define MONGOC_SSL_PRIVATE_H #if !defined (MONGOC_I_AM_A_DRIVER) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #include #include #include #include #include "mongoc-ssl.h" BSON_BEGIN_DECLS bool _mongoc_ssl_check_cert (SSL *ssl, const char *host, bool weak_cert_validation); SSL_CTX *_mongoc_ssl_ctx_new (mongoc_ssl_opt_t *opt); char *_mongoc_ssl_extract_subject (const char *filename); void _mongoc_ssl_init (void); void _mongoc_ssl_cleanup (void); BSON_END_DECLS #endif /* MONGOC_SSL_PRIVATE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-ssl.c0000664000175000017500000003347412673034026022057 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "mongoc-config.h" #ifdef MONGOC_ENABLE_SSL #include #include #include #include #include #include #include #include #include "mongoc-init.h" #include "mongoc-socket.h" #include "mongoc-ssl.h" #include "mongoc-ssl-private.h" #include "mongoc-trace.h" #include "mongoc-thread-private.h" #include "mongoc-util-private.h" /* TODO: we could populate these from a config or something further down the * road for providing defaults */ #ifndef MONGOC_SSL_DEFAULT_TRUST_FILE #define MONGOC_SSL_DEFAULT_TRUST_FILE NULL #endif #ifndef MONGOC_SSL_DEFAULT_TRUST_DIR #define MONGOC_SSL_DEFAULT_TRUST_DIR NULL #endif static mongoc_ssl_opt_t gMongocSslOptDefault = { NULL, NULL, MONGOC_SSL_DEFAULT_TRUST_FILE, MONGOC_SSL_DEFAULT_TRUST_DIR, }; static mongoc_mutex_t * gMongocSslThreadLocks; static void _mongoc_ssl_thread_startup(void); static void _mongoc_ssl_thread_cleanup(void); const mongoc_ssl_opt_t * mongoc_ssl_opt_get_default (void) { return &gMongocSslOptDefault; } /** * _mongoc_ssl_init: * * initialization function for SSL * * This needs to get called early on and is not threadsafe. Called by * mongoc_init. */ void _mongoc_ssl_init (void) { SSL_CTX *ctx; SSL_library_init (); SSL_load_error_strings (); ERR_load_BIO_strings (); OpenSSL_add_all_algorithms (); _mongoc_ssl_thread_startup (); /* * Ensure we also load the ciphers now from the primary thread * or we can run into some weirdness on 64-bit Solaris 10 on * SPARC with openssl 0.9.7. */ ctx = SSL_CTX_new (SSLv23_method ()); if (!ctx) { MONGOC_ERROR ("Failed to initialize OpenSSL."); } SSL_CTX_free (ctx); } void _mongoc_ssl_cleanup (void) { _mongoc_ssl_thread_cleanup (); } static int _mongoc_ssl_password_cb (char *buf, int num, int rwflag, void *user_data) { char *pass = (char *)user_data; int pass_len = (int)strlen (pass); if (num < pass_len + 1) { return 0; } bson_strncpy (buf, pass, num); return pass_len; } /** mongoc_ssl_hostcheck * * rfc 6125 match a given hostname against a given pattern * * Patterns come from DNS common names or subjectAltNames. * * This code is meant to implement RFC 6125 6.4.[1-3] * */ static bool _mongoc_ssl_hostcheck (const char *pattern, const char *hostname) { const char *pattern_label_end; const char *pattern_wildcard; const char *hostname_label_end; size_t prefixlen; size_t suffixlen; pattern_wildcard = strchr (pattern, '*'); if (pattern_wildcard == NULL) { return strcasecmp (pattern, hostname) == 0; } pattern_label_end = strchr (pattern, '.'); /* Bail out on wildcarding in a couple of situations: * o we don't have 2 dots - we're not going to wildcard root tlds * o the wildcard isn't in the left most group (separated by dots) * o the pattern is embedded in an A-label or U-label */ if (pattern_label_end == NULL || strchr (pattern_label_end + 1, '.') == NULL || pattern_wildcard > pattern_label_end || strncasecmp (pattern, "xn--", 4) == 0) { return strcasecmp (pattern, hostname) == 0; } hostname_label_end = strchr (hostname, '.'); /* we know we have a dot in the pattern, we need one in the hostname */ if (hostname_label_end == NULL || strcasecmp (pattern_label_end, hostname_label_end)) { return 0; } /* The wildcard must match at least one character, so the left part of the * hostname is at least as large as the left part of the pattern. */ if ((hostname_label_end - hostname) < (pattern_label_end - pattern)) { return 0; } /* If the left prefix group before the star matches and right of the star * matches... we have a wildcard match */ prefixlen = pattern_wildcard - pattern; suffixlen = pattern_label_end - (pattern_wildcard + 1); return strncasecmp (pattern, hostname, prefixlen) == 0 && strncasecmp (pattern_wildcard + 1, hostname_label_end - suffixlen, suffixlen) == 0; } /** check if a provided cert matches a passed hostname */ bool _mongoc_ssl_check_cert (SSL *ssl, const char *host, bool weak_cert_validation) { X509 *peer; X509_NAME *subject_name; X509_NAME_ENTRY *entry; ASN1_STRING *entry_data; char *check; int length; int idx; int r = 0; long verify_status; size_t addrlen = 0; struct in_addr addr; int i; int n_sans = -1; int target = GEN_DNS; STACK_OF (GENERAL_NAME) * sans = NULL; BSON_ASSERT (ssl); BSON_ASSERT (host); if (weak_cert_validation) { return true; } /** if the host looks like an IP address, match that, otherwise we assume we * have a DNS name */ if (inet_pton (AF_INET, host, &addr)) { target = GEN_IPADD; addrlen = sizeof (struct in_addr); } peer = SSL_get_peer_certificate (ssl); if (!peer) { return false; } verify_status = SSL_get_verify_result (ssl); /** TODO: should we return this somehow? */ if (verify_status == X509_V_OK) { /* get's a stack of alt names that we can iterate through */ sans = (STACK_OF (GENERAL_NAME) *) X509_get_ext_d2i ( (X509 *)peer, NID_subject_alt_name, NULL, NULL); if (sans) { n_sans = sk_GENERAL_NAME_num (sans); /* loop through the stack, or until we find a match */ for (i = 0; i < n_sans && !r; i++) { const GENERAL_NAME *name = sk_GENERAL_NAME_value (sans, i); /* skip entries that can't apply, I.e. IP entries if we've got a * DNS host */ if (name->type == target) { check = (char *)ASN1_STRING_data (name->d.ia5); length = ASN1_STRING_length (name->d.ia5); switch (target) { case GEN_DNS: /* check that we don't have an embedded null byte */ if ((length == bson_strnlen (check, length)) && _mongoc_ssl_hostcheck (check, host)) { r = 1; } break; case GEN_IPADD: if ((length == addrlen) && !memcmp (check, &addr, length)) { r = 1; } break; default: BSON_ASSERT (0); break; } } } GENERAL_NAMES_free (sans); } else { subject_name = X509_get_subject_name (peer); if (subject_name) { idx = -1; i = -1; /* skip to the last common name */ while ((idx = X509_NAME_get_index_by_NID (subject_name, NID_commonName, i)) >= 0) { i = idx; } if (i >= 0) { entry = X509_NAME_get_entry (subject_name, i); entry_data = X509_NAME_ENTRY_get_data (entry); if (entry_data) { /* TODO: I've heard tell that old versions of SSL crap out * when calling ASN1_STRING_to_UTF8 on already utf8 data. * Check up on that */ length = ASN1_STRING_to_UTF8 ((unsigned char **)&check, entry_data); if (length >= 0) { /* check for embedded nulls */ if ((length == bson_strnlen (check, length)) && _mongoc_ssl_hostcheck (check, host)) { r = 1; } OPENSSL_free (check); } } } } } } X509_free (peer); return r; } static bool _mongoc_ssl_setup_ca (SSL_CTX *ctx, const char *cert, const char *cert_dir) { BSON_ASSERT(ctx); BSON_ASSERT(cert || cert_dir); if (!SSL_CTX_load_verify_locations (ctx, cert, cert_dir)) { return 0; } return 1; } static bool _mongoc_ssl_setup_crl (SSL_CTX *ctx, const char *crlfile) { X509_STORE *store; X509_LOOKUP *lookup; int status; store = SSL_CTX_get_cert_store (ctx); X509_STORE_set_flags (store, X509_V_FLAG_CRL_CHECK); lookup = X509_STORE_add_lookup (store, X509_LOOKUP_file ()); status = X509_load_crl_file (lookup, crlfile, X509_FILETYPE_PEM); return status != 0; } static bool _mongoc_ssl_setup_pem_file (SSL_CTX *ctx, const char *pem_file, const char *password) { if (!SSL_CTX_use_certificate_chain_file (ctx, pem_file)) { return 0; } if (password) { SSL_CTX_set_default_passwd_cb_userdata (ctx, (void *)password); SSL_CTX_set_default_passwd_cb (ctx, _mongoc_ssl_password_cb); } if (!(SSL_CTX_use_PrivateKey_file (ctx, pem_file, SSL_FILETYPE_PEM))) { return 0; } if (!(SSL_CTX_check_private_key (ctx))) { return 0; } return 1; } /** * _mongoc_ssl_ctx_new: * * Create a new ssl context declaratively * * The opt.pem_pwd parameter, if passed, must exist for the life of this * context object (for storing and loading the associated pem file) */ SSL_CTX * _mongoc_ssl_ctx_new (mongoc_ssl_opt_t *opt) { SSL_CTX *ctx = NULL; /* * Ensure we are initialized. This is safe to call multiple times. */ mongoc_init (); ctx = SSL_CTX_new (SSLv23_method ()); BSON_ASSERT (ctx); /* SSL_OP_ALL - Activate all bug workaround options, to support buggy client SSL's. * SSL_OP_NO_SSLv2 - Disable SSL v2 support */ SSL_CTX_set_options (ctx, (SSL_OP_ALL | SSL_OP_NO_SSLv2)); /* HIGH - Enable strong ciphers * !EXPORT - Disable export ciphers (40/56 bit) * !aNULL - Disable anonymous auth ciphers * @STRENGTH - Sort ciphers based on strength */ SSL_CTX_set_cipher_list (ctx, "HIGH:!EXPORT:!aNULL@STRENGTH"); /* If renegotiation is needed, don't return from recv() or send() until it's successful. * Note: this is for blocking sockets only. */ SSL_CTX_set_mode (ctx, SSL_MODE_AUTO_RETRY); /* TODO: does this cargo cult actually matter? * Disable session caching (see SERVER-10261) */ SSL_CTX_set_session_cache_mode (ctx, SSL_SESS_CACHE_OFF); /* Load in verification certs, private keys and revocation lists */ if ((!opt->pem_file || _mongoc_ssl_setup_pem_file (ctx, opt->pem_file, opt->pem_pwd)) && (!(opt->ca_file || opt->ca_dir) || _mongoc_ssl_setup_ca (ctx, opt->ca_file, opt->ca_dir)) && (!opt->crl_file || _mongoc_ssl_setup_crl (ctx, opt->crl_file)) ) { return ctx; } else { SSL_CTX_free (ctx); return NULL; } } char * _mongoc_ssl_extract_subject (const char *filename) { X509_NAME *subject = NULL; X509 *cert = NULL; BIO *certbio = NULL; BIO *strbio = NULL; char *str = NULL; int ret; if (!filename) { return NULL; } certbio = BIO_new (BIO_s_file ()); strbio = BIO_new (BIO_s_mem ());; BSON_ASSERT (certbio); BSON_ASSERT (strbio); BIO_read_filename (certbio, filename); if ((cert = PEM_read_bio_X509 (certbio, NULL, 0, NULL))) { if ((subject = X509_get_subject_name (cert))) { ret = X509_NAME_print_ex (strbio, subject, 0, XN_FLAG_RFC2253); if ((ret > 0) && (ret < INT_MAX)) { str = (char *)bson_malloc (ret + 2); BIO_gets (strbio, str, ret + 1); str [ret] = '\0'; } } } if (cert) { X509_free (cert); } if (certbio) { BIO_free (certbio); } if (strbio) { BIO_free (strbio); } return str; } #ifdef _WIN32 static unsigned long _mongoc_ssl_thread_id_callback (void) { unsigned long ret; ret = (unsigned long)GetCurrentThreadId (); return ret; } #else static unsigned long _mongoc_ssl_thread_id_callback (void) { unsigned long ret; ret = (unsigned long)pthread_self (); return ret; } #endif static void _mongoc_ssl_thread_locking_callback (int mode, int type, const char *file, int line) { if (mode & CRYPTO_LOCK) { mongoc_mutex_lock (&gMongocSslThreadLocks[type]); } else { mongoc_mutex_unlock (&gMongocSslThreadLocks[type]); } } static void _mongoc_ssl_thread_startup (void) { int i; gMongocSslThreadLocks = (mongoc_mutex_t *)OPENSSL_malloc (CRYPTO_num_locks () * sizeof (mongoc_mutex_t)); for (i = 0; i < CRYPTO_num_locks (); i++) { mongoc_mutex_init(&gMongocSslThreadLocks[i]); } if (!CRYPTO_get_locking_callback ()) { CRYPTO_set_locking_callback (_mongoc_ssl_thread_locking_callback); CRYPTO_set_id_callback (_mongoc_ssl_thread_id_callback); } } static void _mongoc_ssl_thread_cleanup (void) { int i; if (CRYPTO_get_locking_callback () == _mongoc_ssl_thread_locking_callback) { CRYPTO_set_locking_callback (NULL); CRYPTO_set_id_callback (NULL); } for (i = 0; i < CRYPTO_num_locks (); i++) { mongoc_mutex_destroy (&gMongocSslThreadLocks[i]); } OPENSSL_free (gMongocSslThreadLocks); } #endif mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-ssl.h0000664000175000017500000000224712673034026022056 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_SSL_H #define MONGOC_SSL_H #if !defined (MONGOC_INSIDE) && !defined (MONGOC_COMPILATION) # error "Only can be included directly." #endif #include BSON_BEGIN_DECLS typedef struct _mongoc_ssl_opt_t mongoc_ssl_opt_t; struct _mongoc_ssl_opt_t { const char *pem_file; const char *pem_pwd; const char *ca_file; const char *ca_dir; const char *crl_file; bool weak_cert_validation; void *padding [8]; }; const mongoc_ssl_opt_t *mongoc_ssl_opt_get_default (void) BSON_GNUC_CONST; BSON_END_DECLS #endif /* MONGOC_SSL_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-stream-buffered.c0000664000175000017500000002174112673034026024323 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include "mongoc-buffer-private.h" #include "mongoc-counters-private.h" #include "mongoc-log.h" #include "mongoc-stream-buffered.h" #include "mongoc-stream-private.h" #include "mongoc-trace.h" #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "stream" typedef struct { mongoc_stream_t stream; mongoc_stream_t *base_stream; mongoc_buffer_t buffer; } mongoc_stream_buffered_t; /* *-------------------------------------------------------------------------- * * mongoc_stream_buffered_destroy -- * * Clean up after a mongoc_stream_buffered_t. Free all allocated * resources and release the base stream. * * Returns: * None. * * Side effects: * Everything. * *-------------------------------------------------------------------------- */ static void mongoc_stream_buffered_destroy (mongoc_stream_t *stream) /* IN */ { mongoc_stream_buffered_t *buffered = (mongoc_stream_buffered_t *)stream; BSON_ASSERT (stream); mongoc_stream_destroy(buffered->base_stream); buffered->base_stream = NULL; _mongoc_buffer_destroy (&buffered->buffer); bson_free(stream); mongoc_counter_streams_active_dec(); mongoc_counter_streams_disposed_inc(); } /* *-------------------------------------------------------------------------- * * mongoc_stream_buffered_failed -- * * Called when a stream fails. Useful for streams that differnciate * between failure and cleanup. * Calls mongoc_stream_buffered_destroy() on the stream. * * Returns: * None. * * Side effects: * Everything. * *-------------------------------------------------------------------------- */ static void mongoc_stream_buffered_failed (mongoc_stream_t *stream) /* IN */ { mongoc_stream_buffered_destroy (stream); } /* *-------------------------------------------------------------------------- * * mongoc_stream_buffered_close -- * * Close the underlying stream. The buffered content is still * valid. * * Returns: * The return value of mongoc_stream_close() on the underlying * stream. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static int mongoc_stream_buffered_close (mongoc_stream_t *stream) /* IN */ { mongoc_stream_buffered_t *buffered = (mongoc_stream_buffered_t *)stream; BSON_ASSERT (stream); return mongoc_stream_close(buffered->base_stream); } /* *-------------------------------------------------------------------------- * * mongoc_stream_buffered_flush -- * * Flushes the underlying stream. * * Returns: * The result of flush on the base stream. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static int mongoc_stream_buffered_flush (mongoc_stream_t *stream) /* IN */ { mongoc_stream_buffered_t *buffered = (mongoc_stream_buffered_t *)stream; BSON_ASSERT (buffered); return mongoc_stream_flush(buffered->base_stream); } /* *-------------------------------------------------------------------------- * * mongoc_stream_buffered_writev -- * * Write an iovec to the underlying stream. This write is not * buffered, it passes through to the base stream directly. * * timeout_msec should be the number of milliseconds to wait before * considering the writev as failed. * * Returns: * The number of bytes written or -1 on failure. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static ssize_t mongoc_stream_buffered_writev (mongoc_stream_t *stream, /* IN */ mongoc_iovec_t *iov, /* IN */ size_t iovcnt, /* IN */ int32_t timeout_msec) /* IN */ { mongoc_stream_buffered_t *buffered = (mongoc_stream_buffered_t *)stream; ssize_t ret; ENTRY; BSON_ASSERT (buffered); ret = mongoc_stream_writev(buffered->base_stream, iov, iovcnt, timeout_msec); RETURN (ret); } /* *-------------------------------------------------------------------------- * * mongoc_stream_buffered_readv -- * * Read from the underlying stream. The data will be buffered based * on the buffered streams target buffer size. * * When reading from the underlying stream, we read at least the * requested number of bytes, but try to also fill the stream to * the size of the underlying buffer. * * Note: * This isn't actually a huge savings since we never have more than * one reply waiting for us, but perhaps someday that will be * different. It should help for small replies, however that will * reduce our read() syscalls by 50%. * * Returns: * The number of bytes read or -1 on failure. * * Side effects: * iov[*]->iov_base buffers are filled. * *-------------------------------------------------------------------------- */ static ssize_t mongoc_stream_buffered_readv (mongoc_stream_t *stream, /* IN */ mongoc_iovec_t *iov, /* INOUT */ size_t iovcnt, /* IN */ size_t min_bytes, /* IN */ int32_t timeout_msec) /* IN */ { mongoc_stream_buffered_t *buffered = (mongoc_stream_buffered_t *)stream; bson_error_t error = { 0 }; size_t total_bytes = 0; size_t i; ENTRY; BSON_ASSERT (buffered); for (i = 0; i < iovcnt; i++) { total_bytes += iov[i].iov_len; } if (-1 == _mongoc_buffer_fill (&buffered->buffer, buffered->base_stream, total_bytes, timeout_msec, &error)) { MONGOC_WARNING ("Failure to buffer %u bytes: %s", (unsigned)total_bytes, error.message); RETURN (-1); } BSON_ASSERT (buffered->buffer.len >= total_bytes); for (i = 0; i < iovcnt; i++) { memcpy(iov[i].iov_base, buffered->buffer.data + buffered->buffer.off, iov[i].iov_len); buffered->buffer.off += iov[i].iov_len; buffered->buffer.len -= iov[i].iov_len; } RETURN (total_bytes); } static mongoc_stream_t * _mongoc_stream_buffered_get_base_stream (mongoc_stream_t *stream) /* IN */ { return ((mongoc_stream_buffered_t *)stream)->base_stream; } static bool _mongoc_stream_buffered_check_closed (mongoc_stream_t *stream) /* IN */ { mongoc_stream_buffered_t *buffered = (mongoc_stream_buffered_t *)stream; BSON_ASSERT (stream); return mongoc_stream_check_closed (buffered->base_stream); } /* *-------------------------------------------------------------------------- * * mongoc_stream_buffered_new -- * * Creates a new mongoc_stream_buffered_t. * * This stream will read from an underlying stream and try to read * more data than necessary. It can help lower the number of read() * or recv() syscalls performed. * * @base_stream is considered owned by the resulting stream after * calling this function. * * Returns: * A newly allocated mongoc_stream_t. * * Side effects: * None. * *-------------------------------------------------------------------------- */ mongoc_stream_t * mongoc_stream_buffered_new (mongoc_stream_t *base_stream, /* IN */ size_t buffer_size) /* IN */ { mongoc_stream_buffered_t *stream; BSON_ASSERT (base_stream); stream = (mongoc_stream_buffered_t *)bson_malloc0(sizeof *stream); stream->stream.type = MONGOC_STREAM_BUFFERED; stream->stream.destroy = mongoc_stream_buffered_destroy; stream->stream.failed = mongoc_stream_buffered_failed; stream->stream.close = mongoc_stream_buffered_close; stream->stream.flush = mongoc_stream_buffered_flush; stream->stream.writev = mongoc_stream_buffered_writev; stream->stream.readv = mongoc_stream_buffered_readv; stream->stream.get_base_stream = _mongoc_stream_buffered_get_base_stream; stream->stream.check_closed = _mongoc_stream_buffered_check_closed; stream->base_stream = base_stream; _mongoc_buffer_init (&stream->buffer, NULL, buffer_size, NULL, NULL); mongoc_counter_streams_active_inc(); return (mongoc_stream_t *)stream; } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-stream-buffered.h0000664000175000017500000000204412673034026024323 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_STREAM_BUFFERED_H #define MONGOC_STREAM_BUFFERED_H #if !defined (MONGOC_INSIDE) && !defined (MONGOC_COMPILATION) # error "Only can be included directly." #endif #include #include "mongoc-stream.h" BSON_BEGIN_DECLS mongoc_stream_t *mongoc_stream_buffered_new (mongoc_stream_t *base_stream, size_t buffer_size); BSON_END_DECLS #endif /* MONGOC_STREAM_BUFFERED_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-stream-file.c0000664000175000017500000001173512673034026023462 0ustar jmikolajmikola/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifdef _WIN32 # include # include #endif #include "mongoc-stream-private.h" #include "mongoc-stream-file.h" #include "mongoc-trace.h" /* * TODO: This does not respect timeouts or set O_NONBLOCK. * But that should be fine until it isn't :-) */ struct _mongoc_stream_file_t { mongoc_stream_t vtable; int fd; }; static int _mongoc_stream_file_close (mongoc_stream_t *stream) { mongoc_stream_file_t *file = (mongoc_stream_file_t *)stream; int ret; ENTRY; BSON_ASSERT (file); if (file->fd != -1) { #ifdef _WIN32 ret = _close (file->fd); #else ret = close (file->fd); #endif file->fd = -1; RETURN (ret); } RETURN (0); } static void _mongoc_stream_file_destroy (mongoc_stream_t *stream) { mongoc_stream_file_t *file = (mongoc_stream_file_t *)stream; ENTRY; BSON_ASSERT (file); if (file->fd) { _mongoc_stream_file_close (stream); } bson_free (file); EXIT; } static void _mongoc_stream_file_failed (mongoc_stream_t *stream) { ENTRY; _mongoc_stream_file_destroy (stream); EXIT; } static int _mongoc_stream_file_flush (mongoc_stream_t *stream) /* IN */ { mongoc_stream_file_t *file = (mongoc_stream_file_t *)stream; BSON_ASSERT (file); if (file->fd != -1) { #ifdef _WIN32 return _commit (file->fd); #else return fsync (file->fd); #endif } return 0; } static ssize_t _mongoc_stream_file_readv (mongoc_stream_t *stream, /* IN */ mongoc_iovec_t *iov, /* IN */ size_t iovcnt, /* IN */ size_t min_bytes, /* IN */ int32_t timeout_msec) /* IN */ { mongoc_stream_file_t *file = (mongoc_stream_file_t *)stream; ssize_t ret = 0; #ifdef _WIN32 ssize_t nread; size_t i; ENTRY; for (i = 0; i < iovcnt; i++) { nread = _read (file->fd, iov [i].iov_base, iov [i].iov_len); if (nread < 0) { RETURN (ret ? ret : -1); } else if (nread == 0) { RETURN (ret ? ret : 0); } else { ret += nread; if (nread != iov[i].iov_len) { RETURN (ret ? ret : -1); } } } RETURN (ret); #else ENTRY; ret = readv (file->fd, iov, (int) iovcnt); RETURN (ret); #endif } static ssize_t _mongoc_stream_file_writev (mongoc_stream_t *stream, /* IN */ mongoc_iovec_t *iov, /* IN */ size_t iovcnt, /* IN */ int32_t timeout_msec) /* IN */ { mongoc_stream_file_t *file = (mongoc_stream_file_t *)stream; #ifdef _WIN32 ssize_t ret = 0; ssize_t nwrite; size_t i; for (i = 0; i < iovcnt; i++) { nwrite = _write (file->fd, iov [i].iov_base, iov [i].iov_len); if (nwrite != iov [i].iov_len) { return ret ? ret : -1; } ret += nwrite; } return ret; #else return writev (file->fd, iov, (int) iovcnt); #endif } static bool _mongoc_stream_file_check_closed (mongoc_stream_t *stream) /* IN */ { return false; } mongoc_stream_t * mongoc_stream_file_new (int fd) /* IN */ { mongoc_stream_file_t *stream; BSON_ASSERT (fd != -1); stream = (mongoc_stream_file_t *)bson_malloc0 (sizeof *stream); stream->vtable.type = MONGOC_STREAM_FILE; stream->vtable.close = _mongoc_stream_file_close; stream->vtable.destroy = _mongoc_stream_file_destroy; stream->vtable.failed = _mongoc_stream_file_failed; stream->vtable.flush = _mongoc_stream_file_flush; stream->vtable.readv = _mongoc_stream_file_readv; stream->vtable.writev = _mongoc_stream_file_writev; stream->vtable.check_closed = _mongoc_stream_file_check_closed; stream->fd = fd; return (mongoc_stream_t *)stream; } mongoc_stream_t * mongoc_stream_file_new_for_path (const char *path, /* IN */ int flags, /* IN */ int mode) /* IN */ { int fd = -1; BSON_ASSERT (path); #ifdef _WIN32 if (_sopen_s (&fd, path, (flags | _O_BINARY), _SH_DENYNO, mode) != 0) { fd = -1; } #else fd = open (path, flags, mode); #endif if (fd == -1) { return NULL; } return mongoc_stream_file_new (fd); } int mongoc_stream_file_get_fd (mongoc_stream_file_t *stream) { BSON_ASSERT (stream); return stream->fd; } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-stream-file.h0000664000175000017500000000246512673034026023467 0ustar jmikolajmikola/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_STREAM_FILE_H #define MONGOC_STREAM_FILE_H #if !defined (MONGOC_INSIDE) && !defined (MONGOC_COMPILATION) # error "Only can be included directly." #endif #include "mongoc-stream.h" BSON_BEGIN_DECLS typedef struct _mongoc_stream_file_t mongoc_stream_file_t; mongoc_stream_t *mongoc_stream_file_new (int fd); mongoc_stream_t *mongoc_stream_file_new_for_path (const char *path, int flags, int mode); int mongoc_stream_file_get_fd (mongoc_stream_file_t *stream); BSON_END_DECLS #endif /* MONGOC_STREAM_FILE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-stream-gridfs.c0000664000175000017500000001003112673034026024005 0ustar jmikolajmikola/* * Copyright 2013 MongoDB Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include "mongoc-counters-private.h" #include "mongoc-stream.h" #include "mongoc-stream-private.h" #include "mongoc-gridfs-file.h" #include "mongoc-gridfs-file-private.h" #include "mongoc-trace.h" #include "mongoc-stream-gridfs.h" #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "stream-gridfs" typedef struct { mongoc_stream_t stream; mongoc_gridfs_file_t *file; } mongoc_stream_gridfs_t; static void _mongoc_stream_gridfs_destroy (mongoc_stream_t *stream) { ENTRY; BSON_ASSERT (stream); mongoc_stream_close (stream); bson_free (stream); mongoc_counter_streams_active_dec (); mongoc_counter_streams_disposed_inc (); EXIT; } static void _mongoc_stream_gridfs_failed (mongoc_stream_t *stream) { ENTRY; _mongoc_stream_gridfs_destroy (stream); EXIT; } static int _mongoc_stream_gridfs_close (mongoc_stream_t *stream) { mongoc_stream_gridfs_t *gridfs = (mongoc_stream_gridfs_t *)stream; int ret = 0; ENTRY; BSON_ASSERT (stream); ret = mongoc_gridfs_file_save (gridfs->file); RETURN (ret); } static int _mongoc_stream_gridfs_flush (mongoc_stream_t *stream) { mongoc_stream_gridfs_t *gridfs = (mongoc_stream_gridfs_t *)stream; int ret = 0; ENTRY; BSON_ASSERT (stream); ret = mongoc_gridfs_file_save (gridfs->file); RETURN (ret); } static ssize_t _mongoc_stream_gridfs_readv (mongoc_stream_t *stream, mongoc_iovec_t *iov, size_t iovcnt, size_t min_bytes, int32_t timeout_msec) { mongoc_stream_gridfs_t *file = (mongoc_stream_gridfs_t *)stream; ssize_t ret = 0; ENTRY; BSON_ASSERT (stream); BSON_ASSERT (iov); BSON_ASSERT (iovcnt); BSON_ASSERT (timeout_msec <= INT_MAX); ret = mongoc_gridfs_file_readv (file->file, iov, iovcnt, min_bytes, timeout_msec); mongoc_counter_streams_ingress_add (ret); RETURN (ret); } static ssize_t _mongoc_stream_gridfs_writev (mongoc_stream_t *stream, mongoc_iovec_t *iov, size_t iovcnt, int32_t timeout_msec) { mongoc_stream_gridfs_t *file = (mongoc_stream_gridfs_t *)stream; ssize_t ret = 0; ENTRY; BSON_ASSERT (stream); BSON_ASSERT (iov); BSON_ASSERT (iovcnt); ret = mongoc_gridfs_file_writev (file->file, iov, iovcnt, timeout_msec); if (!ret) { RETURN (ret); } mongoc_counter_streams_egress_add (ret); RETURN (ret); } static bool _mongoc_stream_gridfs_check_closed (mongoc_stream_t *stream) /* IN */ { return false; } mongoc_stream_t * mongoc_stream_gridfs_new (mongoc_gridfs_file_t *file) { mongoc_stream_gridfs_t *stream; ENTRY; BSON_ASSERT (file); stream = (mongoc_stream_gridfs_t *)bson_malloc0 (sizeof *stream); stream->file = file; stream->stream.type = MONGOC_STREAM_GRIDFS; stream->stream.destroy = _mongoc_stream_gridfs_destroy; stream->stream.failed = _mongoc_stream_gridfs_failed; stream->stream.close = _mongoc_stream_gridfs_close; stream->stream.flush = _mongoc_stream_gridfs_flush; stream->stream.writev = _mongoc_stream_gridfs_writev; stream->stream.readv = _mongoc_stream_gridfs_readv; stream->stream.check_closed = _mongoc_stream_gridfs_check_closed; mongoc_counter_streams_active_inc (); RETURN ((mongoc_stream_t *)stream); } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-stream-gridfs.h0000664000175000017500000000175112673034026024023 0ustar jmikolajmikola/* * Copyright 2013 MongoDB Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_STREAM_GRIDFS_H #define MONGOC_STREAM_GRIDFS_H #if !defined (MONGOC_INSIDE) && !defined (MONGOC_COMPILATION) # error "Only can be included directly." #endif #include #include "mongoc-gridfs.h" #include "mongoc-stream.h" BSON_BEGIN_DECLS mongoc_stream_t *mongoc_stream_gridfs_new (mongoc_gridfs_file_t *file); BSON_END_DECLS #endif /* MONGOC_STREAM_GRIDFS_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-stream-private.h0000664000175000017500000000265612673034026024224 0ustar jmikolajmikola/* * Copyright 2013-2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_STREAM_PRIVATE_H #define MONGOC_STREAM_PRIVATE_H #if !defined (MONGOC_I_AM_A_DRIVER) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #include "mongoc-iovec.h" #include "mongoc-stream.h" BSON_BEGIN_DECLS #define MONGOC_STREAM_SOCKET 1 #define MONGOC_STREAM_FILE 2 #define MONGOC_STREAM_BUFFERED 3 #define MONGOC_STREAM_GRIDFS 4 #define MONGOC_STREAM_TLS 5 bool mongoc_stream_wait (mongoc_stream_t *stream, int64_t expire_at); bool _mongoc_stream_writev_full (mongoc_stream_t *stream, mongoc_iovec_t *iov, size_t iovcnt, int32_t timeout_msec, bson_error_t *error); BSON_END_DECLS #endif /* MONGOC_STREAM_PRIVATE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-stream-socket.c0000664000175000017500000001600112673034026024022 0ustar jmikolajmikola/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "mongoc-stream-private.h" #include "mongoc-stream-socket.h" #include "mongoc-trace.h" #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "stream" struct _mongoc_stream_socket_t { mongoc_stream_t vtable; mongoc_socket_t *sock; }; static BSON_INLINE int64_t get_expiration (int32_t timeout_msec) { if (timeout_msec < 0) { return -1; } else if (timeout_msec == 0) { return 0; } else { return (bson_get_monotonic_time () + ((int64_t)timeout_msec * 1000L)); } } static int _mongoc_stream_socket_close (mongoc_stream_t *stream) { mongoc_stream_socket_t *ss = (mongoc_stream_socket_t *)stream; int ret; ENTRY; BSON_ASSERT (ss); if (ss->sock) { ret = mongoc_socket_close (ss->sock); RETURN (ret); } RETURN (0); } static void _mongoc_stream_socket_destroy (mongoc_stream_t *stream) { mongoc_stream_socket_t *ss = (mongoc_stream_socket_t *)stream; ENTRY; BSON_ASSERT (ss); if (ss->sock) { mongoc_socket_destroy (ss->sock); ss->sock = NULL; } bson_free (ss); EXIT; } static void _mongoc_stream_socket_failed (mongoc_stream_t *stream) { ENTRY; _mongoc_stream_socket_destroy (stream); EXIT; } static int _mongoc_stream_socket_setsockopt (mongoc_stream_t *stream, int level, int optname, void *optval, socklen_t optlen) { mongoc_stream_socket_t *ss = (mongoc_stream_socket_t *)stream; int ret; ENTRY; BSON_ASSERT (ss); BSON_ASSERT (ss->sock); ret = mongoc_socket_setsockopt (ss->sock, level, optname, optval, optlen); RETURN (ret); } static int _mongoc_stream_socket_flush (mongoc_stream_t *stream) { ENTRY; RETURN (0); } static ssize_t _mongoc_stream_socket_readv (mongoc_stream_t *stream, mongoc_iovec_t *iov, size_t iovcnt, size_t min_bytes, int32_t timeout_msec) { mongoc_stream_socket_t *ss = (mongoc_stream_socket_t *)stream; int64_t expire_at; ssize_t ret = 0; ssize_t nread; size_t cur = 0; ENTRY; BSON_ASSERT (ss); BSON_ASSERT (ss->sock); expire_at = get_expiration (timeout_msec); /* * This isn't ideal, we should plumb through to recvmsg(), but we * don't actually use this in any way but to a single buffer * currently anyway, so should be just fine. */ for (;;) { nread = mongoc_socket_recv (ss->sock, iov [cur].iov_base, iov [cur].iov_len, 0, expire_at); if (nread <= 0) { if (ret >= (ssize_t)min_bytes) { RETURN (ret); } errno = mongoc_socket_errno (ss->sock); RETURN (-1); } ret += nread; while ((cur < iovcnt) && (nread >= (ssize_t)iov [cur].iov_len)) { nread -= iov [cur++].iov_len; } if (cur == iovcnt) { break; } if (ret >= (ssize_t)min_bytes) { RETURN (ret); } iov [cur].iov_base = ((char *)iov [cur].iov_base) + nread; iov [cur].iov_len -= nread; BSON_ASSERT (iovcnt - cur); BSON_ASSERT (iov [cur].iov_len); } RETURN (ret); } static ssize_t _mongoc_stream_socket_writev (mongoc_stream_t *stream, mongoc_iovec_t *iov, size_t iovcnt, int32_t timeout_msec) { mongoc_stream_socket_t *ss = (mongoc_stream_socket_t *)stream; int64_t expire_at; ssize_t ret; ENTRY; if (ss->sock) { expire_at = get_expiration (timeout_msec); ret = mongoc_socket_sendv (ss->sock, iov, iovcnt, expire_at); errno = mongoc_socket_errno (ss->sock); RETURN (ret); } RETURN (-1); } static ssize_t _mongoc_stream_socket_poll (mongoc_stream_poll_t *streams, size_t nstreams, int32_t timeout_msec) { int i; ssize_t ret = -1; mongoc_socket_poll_t *sds; mongoc_stream_socket_t *ss; ENTRY; sds = (mongoc_socket_poll_t *)bson_malloc(sizeof(*sds) * nstreams); for (i = 0; i < nstreams; i++) { ss = (mongoc_stream_socket_t *)streams[i].stream; if (! ss->sock) { goto CLEANUP; } sds[i].socket = ss->sock; sds[i].events = streams[i].events; } ret = mongoc_socket_poll(sds, nstreams, timeout_msec); if (ret > 0) { for (i = 0; i < nstreams; i++) { streams[i].revents = sds[i].revents; } } CLEANUP: bson_free(sds); RETURN (ret); } mongoc_socket_t * mongoc_stream_socket_get_socket (mongoc_stream_socket_t *stream) /* IN */ { BSON_ASSERT (stream); return stream->sock; } static bool _mongoc_stream_socket_check_closed (mongoc_stream_t *stream) /* IN */ { mongoc_stream_socket_t *ss = (mongoc_stream_socket_t *)stream; ENTRY; BSON_ASSERT (stream); if (ss->sock) { RETURN (mongoc_socket_check_closed (ss->sock)); } RETURN (true); } /* *-------------------------------------------------------------------------- * * mongoc_stream_socket_new -- * * Create a new mongoc_stream_t using the mongoc_socket_t for * read and write underneath. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ mongoc_stream_t * mongoc_stream_socket_new (mongoc_socket_t *sock) /* IN */ { mongoc_stream_socket_t *stream; BSON_ASSERT (sock); stream = (mongoc_stream_socket_t *)bson_malloc0 (sizeof *stream); stream->vtable.type = MONGOC_STREAM_SOCKET; stream->vtable.close = _mongoc_stream_socket_close; stream->vtable.destroy = _mongoc_stream_socket_destroy; stream->vtable.failed = _mongoc_stream_socket_failed; stream->vtable.flush = _mongoc_stream_socket_flush; stream->vtable.readv = _mongoc_stream_socket_readv; stream->vtable.writev = _mongoc_stream_socket_writev; stream->vtable.setsockopt = _mongoc_stream_socket_setsockopt; stream->vtable.check_closed = _mongoc_stream_socket_check_closed; stream->vtable.poll = _mongoc_stream_socket_poll; stream->sock = sock; return (mongoc_stream_t *)stream; } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-stream-socket.h0000664000175000017500000000216612673034026024036 0ustar jmikolajmikola/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_STREAM_SOCKET_H #define MONGOC_STREAM_SOCKET_H #if !defined (MONGOC_INSIDE) && !defined (MONGOC_COMPILATION) # error "Only can be included directly." #endif #include "mongoc-socket.h" #include "mongoc-stream.h" BSON_BEGIN_DECLS typedef struct _mongoc_stream_socket_t mongoc_stream_socket_t; mongoc_stream_t *mongoc_stream_socket_new (mongoc_socket_t *socket); mongoc_socket_t *mongoc_stream_socket_get_socket (mongoc_stream_socket_t *stream); BSON_END_DECLS #endif /* MONGOC_STREAM_SOCKET_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-stream-tls.c0000664000175000017500000005650312673034026023347 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "mongoc-config.h" #ifdef MONGOC_ENABLE_SSL #include #include #include #include #include #include #ifdef _WIN32 # include # include #endif #include "mongoc-counters-private.h" #include "mongoc-errno-private.h" #include "mongoc-stream-tls.h" #include "mongoc-stream-private.h" #include "mongoc-ssl-private.h" #include "mongoc-trace.h" #include "mongoc-log.h" #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "stream-tls" #define MONGOC_STREAM_TLS_BUFFER_SIZE 4096 /** * mongoc_stream_tls_t: * * Private storage for handling callbacks from mongoc_stream and BIO_* * * The one funny wrinkle comes with timeout, which we use statefully to * statefully pass timeouts through from the mongoc-stream api. * * TODO: is there a cleaner way to manage that? */ typedef struct { mongoc_stream_t parent; mongoc_stream_t *base_stream; BIO *bio; SSL_CTX *ctx; int32_t timeout_msec; bool weak_cert_validation; } mongoc_stream_tls_t; static int _mongoc_stream_tls_bio_create (BIO *b); static int _mongoc_stream_tls_bio_destroy (BIO *b); static int _mongoc_stream_tls_bio_read (BIO *b, char *buf, int len); static int _mongoc_stream_tls_bio_write (BIO *b, const char *buf, int len); static long _mongoc_stream_tls_bio_ctrl (BIO *b, int cmd, long num, void *ptr); static int _mongoc_stream_tls_bio_gets (BIO *b, char *buf, int len); static int _mongoc_stream_tls_bio_puts (BIO *b, const char *str); /* Magic vtable to make our BIO shim */ static BIO_METHOD gMongocStreamTlsRawMethods = { BIO_TYPE_FILTER, "mongoc-stream-tls-glue", _mongoc_stream_tls_bio_write, _mongoc_stream_tls_bio_read, _mongoc_stream_tls_bio_puts, _mongoc_stream_tls_bio_gets, _mongoc_stream_tls_bio_ctrl, _mongoc_stream_tls_bio_create, _mongoc_stream_tls_bio_destroy }; /* *-------------------------------------------------------------------------- * * _mongoc_stream_tls_bio_create -- * * BIO callback to create a new BIO instance. * * Returns: * 1 if successful. * * Side effects: * @b is initialized. * *-------------------------------------------------------------------------- */ static int _mongoc_stream_tls_bio_create (BIO *b) { BSON_ASSERT (b); b->init = 1; b->num = 0; b->ptr = NULL; b->flags = 0; return 1; } /* *-------------------------------------------------------------------------- * * _mongoc_stream_tls_bio_destroy -- * * Release resources associated with BIO. * * Returns: * 1 if successful. * * Side effects: * @b is destroyed. * *-------------------------------------------------------------------------- */ static int _mongoc_stream_tls_bio_destroy (BIO *b) { mongoc_stream_tls_t *tls; BSON_ASSERT (b); tls = (mongoc_stream_tls_t *)b->ptr; if (!tls) { return -1; } b->ptr = NULL; b->init = 0; b->flags = 0; tls->bio = NULL; return 1; } /* *-------------------------------------------------------------------------- * * _mongoc_stream_tls_bio_read -- * * Read from the underlying stream to BIO. * * Returns: * -1 on failure; otherwise the number of bytes read. * * Side effects: * @buf is filled with data read from underlying stream. * *-------------------------------------------------------------------------- */ static int _mongoc_stream_tls_bio_read (BIO *b, char *buf, int len) { mongoc_stream_tls_t *tls; int ret; BSON_ASSERT (b); BSON_ASSERT (buf); ENTRY; tls = (mongoc_stream_tls_t *)b->ptr; if (!tls) { RETURN (-1); } errno = 0; ret = (int)mongoc_stream_read (tls->base_stream, buf, len, 0, tls->timeout_msec); BIO_clear_retry_flags (b); if ((ret <= 0) && MONGOC_ERRNO_IS_AGAIN (errno)) { BIO_set_retry_read (b); } RETURN (ret); } /* *-------------------------------------------------------------------------- * * _mongoc_stream_tls_bio_write -- * * Write to the underlying stream on behalf of BIO. * * Returns: * -1 on failure; otherwise the number of bytes written. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static int _mongoc_stream_tls_bio_write (BIO *b, const char *buf, int len) { mongoc_stream_tls_t *tls; mongoc_iovec_t iov; int ret; ENTRY; BSON_ASSERT (b); BSON_ASSERT (buf); tls = (mongoc_stream_tls_t *)b->ptr; if (!tls) { RETURN (-1); } iov.iov_base = (void *)buf; iov.iov_len = len; errno = 0; TRACE("mongoc_stream_writev is expected to write: %d", len); ret = (int)mongoc_stream_writev (tls->base_stream, &iov, 1, tls->timeout_msec); BIO_clear_retry_flags (b); if (len > ret) { TRACE("Returned short write: %d of %d", ret, len); } else { TRACE("Completed the %d", ret); } if (ret <= 0 && MONGOC_ERRNO_IS_AGAIN (errno)) { TRACE("%s", "Requesting a retry"); BIO_set_retry_write (b); } RETURN (ret); } /* *-------------------------------------------------------------------------- * * _mongoc_stream_tls_bio_ctrl -- * * Handle ctrl callback for BIO. * * Returns: * ioctl dependent. * * Side effects: * ioctl dependent. * *-------------------------------------------------------------------------- */ static long _mongoc_stream_tls_bio_ctrl (BIO *b, int cmd, long num, void *ptr) { switch (cmd) { case BIO_CTRL_FLUSH: return 1; default: return 0; } } /* *-------------------------------------------------------------------------- * * _mongoc_stream_tls_bio_gets -- * * BIO callback for gets(). Not supported. * * Returns: * -1 always. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static int _mongoc_stream_tls_bio_gets (BIO *b, char *buf, int len) { return -1; } /* *-------------------------------------------------------------------------- * * _mongoc_stream_tls_bio_puts -- * * BIO callback to perform puts(). Just calls the actual write * callback. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static int _mongoc_stream_tls_bio_puts (BIO *b, const char *str) { return _mongoc_stream_tls_bio_write (b, str, (int)strlen (str)); } /* *-------------------------------------------------------------------------- * * _mongoc_stream_tls_destroy -- * * Cleanup after usage of a mongoc_stream_tls_t. Free all allocated * resources and ensure connections are closed. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static void _mongoc_stream_tls_destroy (mongoc_stream_t *stream) { mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *)stream; BSON_ASSERT (tls); BIO_free_all (tls->bio); tls->bio = NULL; mongoc_stream_destroy (tls->base_stream); tls->base_stream = NULL; SSL_CTX_free (tls->ctx); tls->ctx = NULL; bson_free (stream); mongoc_counter_streams_active_dec(); mongoc_counter_streams_disposed_inc(); } /* *-------------------------------------------------------------------------- * * _mongoc_stream_tls_failed -- * * Called on stream failure. Same as _mongoc_stream_tls_destroy() * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static void _mongoc_stream_tls_failed (mongoc_stream_t *stream) { _mongoc_stream_tls_destroy (stream); } /* *-------------------------------------------------------------------------- * * _mongoc_stream_tls_close -- * * Close the underlying socket. * * Linus dictates that you should not check the result of close() * since there is a race condition with EAGAIN and a new file * descriptor being opened. * * Returns: * 0 on success; otherwise -1. * * Side effects: * The BIO fd is closed. * *-------------------------------------------------------------------------- */ static int _mongoc_stream_tls_close (mongoc_stream_t *stream) { mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *)stream; int ret = 0; ENTRY; BSON_ASSERT (tls); ret = mongoc_stream_close (tls->base_stream); RETURN (ret); } /* *-------------------------------------------------------------------------- * * _mongoc_stream_tls_flush -- * * Flush the underlying stream. * * Returns: * 0 if successful; otherwise -1. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static int _mongoc_stream_tls_flush (mongoc_stream_t *stream) { mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *)stream; BSON_ASSERT (tls); return BIO_flush (tls->bio); } static ssize_t _mongoc_stream_tls_write (mongoc_stream_tls_t *tls, char *buf, size_t buf_len) { ssize_t ret; int64_t now; int64_t expire = 0; ENTRY; BSON_ASSERT (tls); BSON_ASSERT (buf); BSON_ASSERT (buf_len); if (tls->timeout_msec >= 0) { expire = bson_get_monotonic_time () + (tls->timeout_msec * 1000UL); } ret = BIO_write (tls->bio, buf, buf_len); TRACE("BIO_write returned %ld", ret); TRACE("I got ret: %ld and retry: %d", ret, BIO_should_retry (tls->bio)); if (ret <= 0) { return ret; } if (expire) { now = bson_get_monotonic_time (); if ((expire - now) < 0) { if (ret < buf_len) { mongoc_counter_streams_timeout_inc(); } tls->timeout_msec = 0; } else { tls->timeout_msec = (expire - now) / 1000L; } } RETURN (ret); } /* *-------------------------------------------------------------------------- * * _mongoc_stream_tls_writev -- * * Write the iovec to the stream. This function will try to write * all of the bytes or fail. If the number of bytes is not equal * to the number requested, a failure or EOF has occurred. * * Returns: * -1 on failure, otherwise the number of bytes written. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static ssize_t _mongoc_stream_tls_writev (mongoc_stream_t *stream, mongoc_iovec_t *iov, size_t iovcnt, int32_t timeout_msec) { mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *)stream; char buf[MONGOC_STREAM_TLS_BUFFER_SIZE]; ssize_t ret = 0; ssize_t child_ret; size_t i; size_t iov_pos = 0; /* There's a bit of a dance to coalesce vectorized writes into * MONGOC_STREAM_TLS_BUFFER_SIZE'd writes to avoid lots of small tls * packets. * * The basic idea is that we want to combine writes in the buffer if they're * smaller than the buffer, flushing as it gets full. For larger writes, or * the last write in the iovec array, we want to ignore the buffer and just * write immediately. We take care of doing buffer writes by re-invoking * ourself with a single iovec_t, pointing at our stack buffer. */ char *buf_head = buf; char *buf_tail = buf; char *buf_end = buf + MONGOC_STREAM_TLS_BUFFER_SIZE; size_t bytes; char *to_write = NULL; size_t to_write_len; BSON_ASSERT (tls); BSON_ASSERT (iov); BSON_ASSERT (iovcnt); ENTRY; tls->timeout_msec = timeout_msec; for (i = 0; i < iovcnt; i++) { iov_pos = 0; while (iov_pos < iov[i].iov_len) { if (buf_head != buf_tail || ((i + 1 < iovcnt) && ((buf_end - buf_tail) > (iov[i].iov_len - iov_pos)))) { /* If we have either of: * - buffered bytes already * - another iovec to send after this one and we don't have more * bytes to send than the size of the buffer. * * copy into the buffer */ bytes = BSON_MIN (iov[i].iov_len - iov_pos, buf_end - buf_tail); memcpy (buf_tail, (char *) iov[i].iov_base + iov_pos, bytes); buf_tail += bytes; iov_pos += bytes; if (buf_tail == buf_end) { /* If we're full, request send */ to_write = buf_head; to_write_len = buf_tail - buf_head; buf_tail = buf_head = buf; } } else { /* Didn't buffer, so just write it through */ to_write = (char *)iov[i].iov_base + iov_pos; to_write_len = iov[i].iov_len - iov_pos; iov_pos += to_write_len; } if (to_write) { /* We get here if we buffered some bytes and filled the buffer, or * if we didn't buffer and have to send out of the iovec */ child_ret = _mongoc_stream_tls_write (tls, to_write, to_write_len); if (child_ret != to_write_len) { TRACE("Got child_ret: %ld while to_write_len is: %ld", child_ret, to_write_len); } if (child_ret < 0) { TRACE("Returning what I had (%ld) as apposed to the error (%ld, errno:%d)", ret, child_ret, errno); RETURN (ret); } ret += child_ret; if (child_ret < to_write_len) { /* we timed out, so send back what we could send */ RETURN (ret); } to_write = NULL; } } } if (buf_head != buf_tail) { /* If we have any bytes buffered, send */ child_ret = _mongoc_stream_tls_write (tls, buf_head, buf_tail - buf_head); if (child_ret < 0) { RETURN (child_ret); } ret += child_ret; } if (ret >= 0) { mongoc_counter_streams_egress_add (ret); } RETURN (ret); } /* *-------------------------------------------------------------------------- * * _mongoc_stream_tls_readv -- * * Read from the stream into iov. This function will try to read * all of the bytes or fail. If the number of bytes is not equal * to the number requested, a failure or EOF has occurred. * * Returns: * -1 on failure, 0 on EOF, otherwise the number of bytes read. * * Side effects: * iov buffers will be written to. * *-------------------------------------------------------------------------- */ static ssize_t _mongoc_stream_tls_readv (mongoc_stream_t *stream, mongoc_iovec_t *iov, size_t iovcnt, size_t min_bytes, int32_t timeout_msec) { mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *)stream; ssize_t ret = 0; size_t i; int read_ret; size_t iov_pos = 0; int64_t now; int64_t expire = 0; ENTRY; BSON_ASSERT (tls); BSON_ASSERT (iov); BSON_ASSERT (iovcnt); tls->timeout_msec = timeout_msec; if (timeout_msec >= 0) { expire = bson_get_monotonic_time () + (timeout_msec * 1000UL); } for (i = 0; i < iovcnt; i++) { iov_pos = 0; while (iov_pos < iov[i].iov_len) { read_ret = BIO_read (tls->bio, (char *)iov[i].iov_base + iov_pos, (int)(iov[i].iov_len - iov_pos)); /* https://www.openssl.org/docs/crypto/BIO_should_retry.html: * * If BIO_should_retry() returns false then the precise "error * condition" depends on the BIO type that caused it and the return * code of the BIO operation. For example if a call to BIO_read() on a * socket BIO returns 0 and BIO_should_retry() is false then the cause * will be that the connection closed. */ if (read_ret < 0 || (read_ret == 0 && !BIO_should_retry (tls->bio))) { return -1; } if (expire) { now = bson_get_monotonic_time (); if ((expire - now) < 0) { if (read_ret == 0) { mongoc_counter_streams_timeout_inc(); #ifdef _WIN32 errno = WSAETIMEDOUT; #else errno = ETIMEDOUT; #endif RETURN (-1); } tls->timeout_msec = 0; } else { tls->timeout_msec = (expire - now) / 1000L; } } ret += read_ret; if ((size_t)ret >= min_bytes) { mongoc_counter_streams_ingress_add(ret); RETURN (ret); } iov_pos += read_ret; } } if (ret >= 0) { mongoc_counter_streams_ingress_add(ret); } RETURN (ret); } /* *-------------------------------------------------------------------------- * * _mongoc_stream_tls_setsockopt -- * * Perform a setsockopt on the underlying stream. * * Returns: * -1 on failure, otherwise opt specific value. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static int _mongoc_stream_tls_setsockopt (mongoc_stream_t *stream, int level, int optname, void *optval, socklen_t optlen) { mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *)stream; BSON_ASSERT (tls); return mongoc_stream_setsockopt (tls->base_stream, level, optname, optval, optlen); } /** * mongoc_stream_tls_do_handshake: * * force an ssl handshake * * This will happen on the first read or write otherwise */ bool mongoc_stream_tls_do_handshake (mongoc_stream_t *stream, int32_t timeout_msec) { mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *)stream; BSON_ASSERT (tls); tls->timeout_msec = timeout_msec; if (BIO_do_handshake (tls->bio) == 1) { return true; } if (!timeout_msec) { return false; } if (!errno) { #ifdef _WIN32 errno = WSAETIMEDOUT; #else errno = ETIMEDOUT; #endif } return false; } /** * mongoc_stream_tls_should_retry: * * If the stream should be retried */ bool mongoc_stream_tls_should_retry (mongoc_stream_t *stream) { mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *)stream; BSON_ASSERT (tls); return BIO_should_retry (tls->bio); } /** * mongoc_stream_tls_should_read: * * If the stream should read */ bool mongoc_stream_tls_should_read (mongoc_stream_t *stream) { mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *)stream; BSON_ASSERT (tls); return BIO_should_read (tls->bio); } /** * mongoc_stream_tls_should_write: * * If the stream should write */ bool mongoc_stream_tls_should_write (mongoc_stream_t *stream) { mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *)stream; BSON_ASSERT (tls); return BIO_should_write (tls->bio); } /** * mongoc_stream_tls_check_cert: * * check the cert returned by the other party */ bool mongoc_stream_tls_check_cert (mongoc_stream_t *stream, const char *host) { mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *)stream; SSL *ssl; BSON_ASSERT (tls); BSON_ASSERT (host); BIO_get_ssl (tls->bio, &ssl); return _mongoc_ssl_check_cert (ssl, host, tls->weak_cert_validation); } static mongoc_stream_t * _mongoc_stream_tls_get_base_stream (mongoc_stream_t *stream) { return ((mongoc_stream_tls_t *)stream)->base_stream; } static bool _mongoc_stream_tls_check_closed (mongoc_stream_t *stream) /* IN */ { mongoc_stream_tls_t *tls = (mongoc_stream_tls_t *)stream; BSON_ASSERT (stream); return mongoc_stream_check_closed (tls->base_stream); } /* *-------------------------------------------------------------------------- * * mongoc_stream_tls_new -- * * Creates a new mongoc_stream_tls_t to communicate with a remote * server using a TLS stream. * * @base_stream should be a stream that will become owned by the * resulting tls stream. It will be used for raw I/O. * * @trust_store_dir should be a path to the SSL cert db to use for * verifying trust of the remote server. * * Returns: * NULL on failure, otherwise a mongoc_stream_t. * * Side effects: * None. * *-------------------------------------------------------------------------- */ mongoc_stream_t * mongoc_stream_tls_new (mongoc_stream_t *base_stream, mongoc_ssl_opt_t *opt, int client) { mongoc_stream_tls_t *tls; SSL_CTX *ssl_ctx = NULL; BIO *bio_ssl = NULL; BIO *bio_mongoc_shim = NULL; BSON_ASSERT(base_stream); BSON_ASSERT(opt); ssl_ctx = _mongoc_ssl_ctx_new (opt); if (!ssl_ctx) { return NULL; } bio_ssl = BIO_new_ssl (ssl_ctx, client); if (!bio_ssl) { return NULL; } bio_mongoc_shim = BIO_new (&gMongocStreamTlsRawMethods); if (!bio_mongoc_shim) { BIO_free_all (bio_ssl); return NULL; } BIO_push (bio_ssl, bio_mongoc_shim); tls = (mongoc_stream_tls_t *)bson_malloc0 (sizeof *tls); tls->base_stream = base_stream; tls->parent.type = MONGOC_STREAM_TLS; tls->parent.destroy = _mongoc_stream_tls_destroy; tls->parent.failed = _mongoc_stream_tls_failed; tls->parent.close = _mongoc_stream_tls_close; tls->parent.flush = _mongoc_stream_tls_flush; tls->parent.writev = _mongoc_stream_tls_writev; tls->parent.readv = _mongoc_stream_tls_readv; tls->parent.setsockopt = _mongoc_stream_tls_setsockopt; tls->parent.get_base_stream = _mongoc_stream_tls_get_base_stream; tls->parent.check_closed = _mongoc_stream_tls_check_closed; tls->weak_cert_validation = opt->weak_cert_validation; tls->bio = bio_ssl; tls->ctx = ssl_ctx; tls->timeout_msec = -1; bio_mongoc_shim->ptr = tls; mongoc_counter_streams_active_inc(); return (mongoc_stream_t *)tls; } #endif mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-stream-tls.h0000664000175000017500000000323212673034026023343 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_STREAM_TLS_H #define MONGOC_STREAM_TLS_H #if !defined (MONGOC_INSIDE) && !defined (MONGOC_COMPILATION) # error "Only can be included directly." #endif #include #include "mongoc-ssl.h" #include "mongoc-stream.h" BSON_BEGIN_DECLS bool mongoc_stream_tls_do_handshake (mongoc_stream_t *stream, int32_t timeout_msec); bool mongoc_stream_tls_should_retry (mongoc_stream_t *stream); bool mongoc_stream_tls_should_read (mongoc_stream_t *stream); bool mongoc_stream_tls_should_write (mongoc_stream_t *stream); bool mongoc_stream_tls_check_cert (mongoc_stream_t *stream, const char *host); mongoc_stream_t *mongoc_stream_tls_new (mongoc_stream_t *base_stream, mongoc_ssl_opt_t *opt, int client); BSON_END_DECLS #endif /* MONGOC_STREAM_TLS_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-stream.c0000664000175000017500000002647012673034026022547 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include "mongoc-array-private.h" #include "mongoc-buffer-private.h" #include "mongoc-error.h" #include "mongoc-errno-private.h" #include "mongoc-flags.h" #include "mongoc-log.h" #include "mongoc-opcode.h" #include "mongoc-rpc-private.h" #include "mongoc-stream.h" #include "mongoc-stream-private.h" #include "mongoc-trace.h" #include "mongoc-util-private.h" #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "stream" #ifndef MONGOC_DEFAULT_TIMEOUT_MSEC # define MONGOC_DEFAULT_TIMEOUT_MSEC (60L * 60L * 1000L) #endif /** * mongoc_stream_close: * @stream: A mongoc_stream_t. * * Closes the underlying file-descriptor used by @stream. * * Returns: 0 on success, -1 on failure. */ int mongoc_stream_close (mongoc_stream_t *stream) { int ret; ENTRY; BSON_ASSERT (stream); BSON_ASSERT (stream->close); ret = stream->close(stream); RETURN (ret); } /** * mongoc_stream_failed: * @stream: A mongoc_stream_t. * * Frees any resources referenced by @stream, including the memory allocation * for @stream. * This handler is called upon stream failure, such as network errors, invalid replies * or replicaset reconfigures deleteing the stream */ void mongoc_stream_failed (mongoc_stream_t *stream) { ENTRY; BSON_ASSERT (stream); if (stream->failed) { stream->failed(stream); } else { stream->destroy(stream); } EXIT; } /** * mongoc_stream_destroy: * @stream: A mongoc_stream_t. * * Frees any resources referenced by @stream, including the memory allocation * for @stream. */ void mongoc_stream_destroy (mongoc_stream_t *stream) { ENTRY; BSON_ASSERT (stream); BSON_ASSERT (stream->destroy); stream->destroy(stream); EXIT; } /** * mongoc_stream_flush: * @stream: A mongoc_stream_t. * * Flushes the data in the underlying stream to the transport. * * Returns: 0 on success, -1 on failure. */ int mongoc_stream_flush (mongoc_stream_t *stream) { BSON_ASSERT (stream); return stream->flush(stream); } /** * mongoc_stream_writev: * @stream: A mongoc_stream_t. * @iov: An array of iovec to write to the stream. * @iovcnt: The number of elements in @iov. * * Writes an array of iovec buffers to the underlying stream. * * Returns: the number of bytes written, or -1 upon failure. */ ssize_t mongoc_stream_writev (mongoc_stream_t *stream, mongoc_iovec_t *iov, size_t iovcnt, int32_t timeout_msec) { ssize_t ret; ENTRY; BSON_ASSERT (stream); BSON_ASSERT (iov); BSON_ASSERT (iovcnt); BSON_ASSERT (stream->writev); if (timeout_msec < 0) { timeout_msec = MONGOC_DEFAULT_TIMEOUT_MSEC; } DUMP_IOVEC (writev, iov, iovcnt); ret = stream->writev(stream, iov, iovcnt, timeout_msec); RETURN (ret); } /** * mongoc_stream_write: * @stream: A mongoc_stream_t. * @buf: A buffer to write. * @count: The number of bytes to write into @buf. * * Simplified access to mongoc_stream_writev(). Creates a single iovec * with the buffer provided. * * Returns: -1 on failure, otherwise the number of bytes write. */ ssize_t mongoc_stream_write (mongoc_stream_t *stream, void *buf, size_t count, int32_t timeout_msec) { mongoc_iovec_t iov; ssize_t ret; ENTRY; BSON_ASSERT (stream); BSON_ASSERT (buf); iov.iov_base = buf; iov.iov_len = count; BSON_ASSERT (stream->writev); ret = mongoc_stream_writev (stream, &iov, 1, timeout_msec); RETURN (ret); } /** * mongoc_stream_readv: * @stream: A mongoc_stream_t. * @iov: An array of iovec containing the location and sizes to read. * @iovcnt: the number of elements in @iov. * @min_bytes: the minumum number of bytes to return, or -1. * * Reads into the various buffers pointed to by @iov and associated * buffer lengths. * * If @min_bytes is specified, then at least min_bytes will be returned unless * eof is encountered. This may result in ETIMEDOUT * * Returns: the number of bytes read or -1 on failure. */ ssize_t mongoc_stream_readv (mongoc_stream_t *stream, mongoc_iovec_t *iov, size_t iovcnt, size_t min_bytes, int32_t timeout_msec) { ssize_t ret; ENTRY; BSON_ASSERT (stream); BSON_ASSERT (iov); BSON_ASSERT (iovcnt); BSON_ASSERT (stream->readv); ret = stream->readv (stream, iov, iovcnt, min_bytes, timeout_msec); if (ret >= 0) { DUMP_IOVEC (readv, iov, iovcnt); } RETURN (ret); } /** * mongoc_stream_read: * @stream: A mongoc_stream_t. * @buf: A buffer to write into. * @count: The number of bytes to write into @buf. * @min_bytes: The minimum number of bytes to receive * * Simplified access to mongoc_stream_readv(). Creates a single iovec * with the buffer provided. * * If @min_bytes is specified, then at least min_bytes will be returned unless * eof is encountered. This may result in ETIMEDOUT * * Returns: -1 on failure, otherwise the number of bytes read. */ ssize_t mongoc_stream_read (mongoc_stream_t *stream, void *buf, size_t count, size_t min_bytes, int32_t timeout_msec) { mongoc_iovec_t iov; ssize_t ret; ENTRY; BSON_ASSERT (stream); BSON_ASSERT (buf); iov.iov_base = buf; iov.iov_len = count; BSON_ASSERT (stream->readv); ret = mongoc_stream_readv (stream, &iov, 1, min_bytes, timeout_msec); RETURN (ret); } int mongoc_stream_setsockopt (mongoc_stream_t *stream, int level, int optname, void *optval, socklen_t optlen) { BSON_ASSERT (stream); if (stream->setsockopt) { return stream->setsockopt(stream, level, optname, optval, optlen); } return 0; } mongoc_stream_t * mongoc_stream_get_base_stream (mongoc_stream_t *stream) /* IN */ { BSON_ASSERT (stream); if (stream->get_base_stream) { return stream->get_base_stream (stream); } return stream; } static mongoc_stream_t * mongoc_stream_get_root_stream (mongoc_stream_t *stream) { BSON_ASSERT (stream); while (stream->get_base_stream) { stream = stream->get_base_stream (stream); } return stream; } ssize_t mongoc_stream_poll (mongoc_stream_poll_t *streams, size_t nstreams, int32_t timeout) { mongoc_stream_poll_t *poller = (mongoc_stream_poll_t *)bson_malloc(sizeof(*poller) * nstreams); int i; int last_type = 0; ssize_t rval = -1; errno = 0; for (i = 0; i < nstreams; i++) { poller[i].stream = mongoc_stream_get_root_stream(streams[i].stream); poller[i].events = streams[i].events; poller[i].revents = 0; if (i == 0) { last_type = poller[i].stream->type; } else if (last_type != poller[i].stream->type) { errno = EINVAL; goto CLEANUP; } } if (! poller[0].stream->poll) { errno = EINVAL; goto CLEANUP; } rval = poller[0].stream->poll(poller, nstreams, timeout); if (rval > 0) { for (i = 0; i < nstreams; i++) { streams[i].revents = poller[i].revents; } } CLEANUP: bson_free(poller); return rval; } /* *-------------------------------------------------------------------------- * * mongoc_stream_wait -- * * Internal helper, poll a single stream until it connects. * * For now, only the POLLOUT (connected) event is supported. * * @expire_at should be an absolute time at which to expire using * the monotonic clock (bson_get_monotonic_time(), which is in * microseconds). expire_at of 0 or -1 is prohibited. * * Returns: * true if an event matched. otherwise false. * a timeout will return false. * * Side effects: * None. * *-------------------------------------------------------------------------- */ bool mongoc_stream_wait (mongoc_stream_t *stream, int64_t expire_at) { mongoc_stream_poll_t poller; int64_t now; int32_t timeout_msec; ssize_t ret; ENTRY; BSON_ASSERT (stream); BSON_ASSERT (expire_at > 0); poller.stream = stream; poller.events = POLLOUT; poller.revents = 0; now = bson_get_monotonic_time(); for (;;) { /* TODO CDRIVER-804 use int64_t for timeouts consistently */ timeout_msec = (int32_t) BSON_MIN ((expire_at - now) / 1000L, INT32_MAX); if (timeout_msec < 0) { timeout_msec = 0; } ret = mongoc_stream_poll (&poller, 1, timeout_msec); if (ret > 0) { /* an event happened, return true if POLLOUT else false */ RETURN (0 != (poller.revents & POLLOUT)); } else if (ret < 0) { /* poll itself failed */ TRACE("errno is: %d", errno); if (MONGOC_ERRNO_IS_AGAIN(errno)) { now = bson_get_monotonic_time(); if (expire_at < now) { RETURN (false); } else { continue; } } else { /* poll failed for some non-transient reason */ RETURN (false); } } else { /* poll timed out */ RETURN (false); } } return true; } bool mongoc_stream_check_closed (mongoc_stream_t *stream) { int ret; ENTRY; if (!stream) { return true; } ret = stream->check_closed(stream); RETURN (ret); } bool _mongoc_stream_writev_full (mongoc_stream_t *stream, mongoc_iovec_t *iov, size_t iovcnt, int32_t timeout_msec, bson_error_t *error) { size_t total_bytes = 0; int i; ssize_t r; ENTRY; for (i = 0; i < iovcnt; i++) { total_bytes += iov[i].iov_len; } r = mongoc_stream_writev(stream, iov, iovcnt, timeout_msec); TRACE("writev returned: %ld", r); if (r < 0) { if (error) { char buf[128]; char *errstr; errstr = bson_strerror_r(errno, buf, sizeof(buf)); bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, "Failure during socket delivery: %s (%d)", errstr, errno); } RETURN(false); } if (r != total_bytes) { bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, "Failure to send all requested bytes (only sent: %" PRIu64 "/%" PRId64 " in %dms) during socket delivery", (uint64_t) r, (int64_t)total_bytes, timeout_msec); RETURN(false); } RETURN(true); } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-stream.h0000664000175000017500000001223512673034026022546 0ustar jmikolajmikola/* * Copyright 2013-2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_STREAM_H #define MONGOC_STREAM_H #if !defined (MONGOC_INSIDE) && !defined (MONGOC_COMPILATION) # error "Only can be included directly." #endif #include "mongoc-iovec.h" #include "mongoc-socket.h" BSON_BEGIN_DECLS typedef struct _mongoc_stream_t mongoc_stream_t; typedef struct _mongoc_stream_poll_t { mongoc_stream_t *stream; int events; int revents; } mongoc_stream_poll_t; struct _mongoc_stream_t { int type; void (*destroy) (mongoc_stream_t *stream); int (*close) (mongoc_stream_t *stream); int (*flush) (mongoc_stream_t *stream); ssize_t (*writev) (mongoc_stream_t *stream, mongoc_iovec_t *iov, size_t iovcnt, int32_t timeout_msec); ssize_t (*readv) (mongoc_stream_t *stream, mongoc_iovec_t *iov, size_t iovcnt, size_t min_bytes, int32_t timeout_msec); int (*setsockopt) (mongoc_stream_t *stream, int level, int optname, void *optval, socklen_t optlen); mongoc_stream_t *(*get_base_stream) (mongoc_stream_t *stream); bool (*check_closed) (mongoc_stream_t *stream); ssize_t (*poll) (mongoc_stream_poll_t *streams, size_t nstreams, int32_t timeout); void (*failed) (mongoc_stream_t *stream); void *padding [5]; }; mongoc_stream_t *mongoc_stream_get_base_stream (mongoc_stream_t *stream); int mongoc_stream_close (mongoc_stream_t *stream); void mongoc_stream_destroy (mongoc_stream_t *stream); void mongoc_stream_failed (mongoc_stream_t *stream); int mongoc_stream_flush (mongoc_stream_t *stream); ssize_t mongoc_stream_writev (mongoc_stream_t *stream, mongoc_iovec_t *iov, size_t iovcnt, int32_t timeout_msec); ssize_t mongoc_stream_write (mongoc_stream_t *stream, void *buf, size_t count, int32_t timeout_msec); ssize_t mongoc_stream_readv (mongoc_stream_t *stream, mongoc_iovec_t *iov, size_t iovcnt, size_t min_bytes, int32_t timeout_msec); ssize_t mongoc_stream_read (mongoc_stream_t *stream, void *buf, size_t count, size_t min_bytes, int32_t timeout_msec); int mongoc_stream_setsockopt (mongoc_stream_t *stream, int level, int optname, void *optval, socklen_t optlen); bool mongoc_stream_check_closed (mongoc_stream_t *stream); ssize_t mongoc_stream_poll (mongoc_stream_poll_t *streams, size_t nstreams, int32_t timeout); BSON_END_DECLS #endif /* MONGOC_STREAM_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-thread-private.h0000664000175000017500000001101112673034026024161 0ustar jmikolajmikola/* * Copyright 2013 MongoDB Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_THREAD_PRIVATE_H #define MONGOC_THREAD_PRIVATE_H #if !defined (MONGOC_I_AM_A_DRIVER) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #include #include "mongoc-config.h" #if !defined(_WIN32) # include # define MONGOC_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER # define mongoc_cond_t pthread_cond_t # define mongoc_cond_broadcast pthread_cond_broadcast # define mongoc_cond_init(_n) pthread_cond_init((_n), NULL) # define mongoc_cond_wait pthread_cond_wait # define mongoc_cond_signal pthread_cond_signal static BSON_INLINE int mongoc_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mutex, int64_t timeout_msec) { struct timespec to; struct timeval tv; int64_t msec; bson_gettimeofday (&tv); msec = ((int64_t)tv.tv_sec * 1000) + (tv.tv_usec / 1000) + timeout_msec; to.tv_sec = msec / 1000; to.tv_nsec = (msec % 1000) * 1000 * 1000; return pthread_cond_timedwait (cond, mutex, &to); } # define mongoc_cond_destroy pthread_cond_destroy # define mongoc_mutex_t pthread_mutex_t # define mongoc_mutex_init(_n) pthread_mutex_init((_n), NULL) # define mongoc_mutex_lock pthread_mutex_lock # define mongoc_mutex_unlock pthread_mutex_unlock # define mongoc_mutex_destroy pthread_mutex_destroy # define mongoc_thread_t pthread_t # define mongoc_thread_create(_t,_f,_d) pthread_create((_t), NULL, (_f), (_d)) # define mongoc_thread_join(_n) pthread_join((_n), NULL) # define mongoc_once_t pthread_once_t # define mongoc_once pthread_once # define MONGOC_ONCE_FUN(n) void n(void) # define MONGOC_ONCE_RETURN return # ifdef _PTHREAD_ONCE_INIT_NEEDS_BRACES # define MONGOC_ONCE_INIT {PTHREAD_ONCE_INIT} # else # define MONGOC_ONCE_INIT PTHREAD_ONCE_INIT # endif #else # define mongoc_thread_t HANDLE static BSON_INLINE int mongoc_thread_create (mongoc_thread_t *thread, void *(*cb)(void *), void *arg) { *thread = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) cb, arg, 0, NULL); return 0; } # define mongoc_thread_join(_n) WaitForSingleObject((_n), INFINITE) # define mongoc_mutex_t CRITICAL_SECTION # define mongoc_mutex_init InitializeCriticalSection # define mongoc_mutex_lock EnterCriticalSection # define mongoc_mutex_unlock LeaveCriticalSection # define mongoc_mutex_destroy DeleteCriticalSection # define mongoc_cond_t CONDITION_VARIABLE # define mongoc_cond_init InitializeConditionVariable # define mongoc_cond_wait(_c, _m) mongoc_cond_timedwait((_c), (_m), INFINITE) static BSON_INLINE int mongoc_cond_timedwait (mongoc_cond_t *cond, mongoc_mutex_t *mutex, int64_t timeout_msec) { int r; if (SleepConditionVariableCS(cond, mutex, timeout_msec)) { return 0; } else { r = GetLastError(); if (r == WAIT_TIMEOUT || r == ERROR_TIMEOUT) { return WSAETIMEDOUT; } else { return EINVAL; } } } # define mongoc_cond_signal WakeConditionVariable # define mongoc_cond_broadcast WakeAllConditionVariable static BSON_INLINE int mongoc_cond_destroy (mongoc_cond_t *_ignored) { return 0; } # define mongoc_once_t INIT_ONCE # define MONGOC_ONCE_INIT INIT_ONCE_STATIC_INIT # define mongoc_once(o, c) InitOnceExecuteOnce(o, c, NULL, NULL) # define MONGOC_ONCE_FUN(n) BOOL CALLBACK n(PINIT_ONCE _ignored_a, PVOID _ignored_b, PVOID *_ignored_c) # define MONGOC_ONCE_RETURN return true #endif #endif /* MONGOC_THREAD_PRIVATE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-topology-description-private.h0000664000175000017500000000707712673034026027130 0ustar jmikolajmikola/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_TOPOLOGY_DESCRIPTION_PRIVATE_H #define MONGOC_TOPOLOGY_DESCRIPTION_PRIVATE_H #include "mongoc-set-private.h" #include "mongoc-server-description.h" #define MONGOC_SS_DEFAULT_TIMEOUT_MS 30000 #define MONGOC_SS_DEFAULT_LOCAL_THRESHOLD_MS 15 typedef enum { MONGOC_TOPOLOGY_UNKNOWN, MONGOC_TOPOLOGY_SHARDED, MONGOC_TOPOLOGY_RS_NO_PRIMARY, MONGOC_TOPOLOGY_RS_WITH_PRIMARY, MONGOC_TOPOLOGY_SINGLE, MONGOC_TOPOLOGY_DESCRIPTION_TYPES } mongoc_topology_description_type_t; typedef struct _mongoc_topology_description_t { mongoc_topology_description_type_t type; mongoc_set_t *servers; char *set_name; int64_t max_set_version; bson_oid_t max_election_id; bool compatible; char *compatibility_error; uint32_t max_server_id; bool stale; } mongoc_topology_description_t; typedef enum { MONGOC_SS_READ, MONGOC_SS_WRITE } mongoc_ss_optype_t; void mongoc_topology_description_init (mongoc_topology_description_t *description, mongoc_topology_description_type_t type); void mongoc_topology_description_destroy (mongoc_topology_description_t *description); void mongoc_topology_description_handle_ismaster ( mongoc_topology_description_t *topology, mongoc_server_description_t *sd, const bson_t *reply, int64_t rtt_msec, bson_error_t *error); mongoc_server_description_t * mongoc_topology_description_select (mongoc_topology_description_t *description, mongoc_ss_optype_t optype, const mongoc_read_prefs_t *read_pref, int64_t local_threshold_ms); mongoc_server_description_t * mongoc_topology_description_server_by_id (mongoc_topology_description_t *description, uint32_t id, bson_error_t *error); void mongoc_topology_description_suitable_servers ( mongoc_array_t *set, /* OUT */ mongoc_ss_optype_t optype, mongoc_topology_description_t *topology, const mongoc_read_prefs_t *read_pref, size_t local_threshold_ms); void mongoc_topology_description_invalidate_server (mongoc_topology_description_t *topology, uint32_t id); bool mongoc_topology_description_add_server (mongoc_topology_description_t *topology, const char *server, uint32_t *id /* OUT */); #endif /* MONGOC_TOPOLOGY_DESCRIPTION_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-topology-description.c0000664000175000017500000013051012673034026025440 0ustar jmikolajmikola/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "mongoc-array-private.h" #include "mongoc-error.h" #include "mongoc-server-description-private.h" #include "mongoc-topology-description-private.h" #include "mongoc-trace.h" #include "mongoc-util-private.h" static void _mongoc_topology_server_dtor (void *server_, void *ctx_) { mongoc_server_description_destroy ((mongoc_server_description_t *)server_); } /* *-------------------------------------------------------------------------- * * mongoc_topology_description_init -- * * Initialize the given topology description * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void mongoc_topology_description_init (mongoc_topology_description_t *description, mongoc_topology_description_type_t type) { ENTRY; BSON_ASSERT (description); BSON_ASSERT (type == MONGOC_TOPOLOGY_UNKNOWN || type == MONGOC_TOPOLOGY_SINGLE || type == MONGOC_TOPOLOGY_RS_NO_PRIMARY); memset (description, 0, sizeof (*description)); description->type = type; description->servers = mongoc_set_new(8, _mongoc_topology_server_dtor, NULL); description->set_name = NULL; description->max_set_version = MONGOC_NO_SET_VERSION; description->compatible = true; description->compatibility_error = NULL; description->stale = true; EXIT; } /* *-------------------------------------------------------------------------- * * mongoc_topology_description_destroy -- * * Destroy allocated resources within @description * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ void mongoc_topology_description_destroy (mongoc_topology_description_t *description) { ENTRY; BSON_ASSERT(description); mongoc_set_destroy(description->servers); if (description->set_name) { bson_free (description->set_name); } if (description->compatibility_error) { bson_free (description->compatibility_error); } EXIT; } /* find the primary, then stop iterating */ static bool _mongoc_topology_description_has_primary_cb (void *item, void *ctx /* OUT */) { mongoc_server_description_t *server = (mongoc_server_description_t *)item; mongoc_server_description_t **primary = (mongoc_server_description_t **)ctx; /* TODO should this include MONGOS? */ if (server->type == MONGOC_SERVER_RS_PRIMARY || server->type == MONGOC_SERVER_STANDALONE) { *primary = (mongoc_server_description_t *)item; return false; } return true; } /* *-------------------------------------------------------------------------- * * _mongoc_topology_description_has_primary -- * * If topology has a primary, return it. * * Returns: * A pointer to the primary, or NULL. * * Side effects: * None * *-------------------------------------------------------------------------- */ static mongoc_server_description_t * _mongoc_topology_description_has_primary (mongoc_topology_description_t *description) { mongoc_server_description_t *primary = NULL; mongoc_set_for_each(description->servers, _mongoc_topology_description_has_primary_cb, &primary); return primary; } /* *-------------------------------------------------------------------------- * * _mongoc_topology_description_later_election -- * * Check if we've seen a more recent election in the replica set * than this server has. * * Returns: * True if the topology description's max replica set version plus * election id is later than the server description's. * * Side effects: * None * *-------------------------------------------------------------------------- */ static bool _mongoc_topology_description_later_election (mongoc_topology_description_t *td, mongoc_server_description_t *sd) { /* initially max_set_version is -1 and max_election_id is zeroed */ return td->max_set_version > sd->set_version || (td->max_set_version == sd->set_version && bson_oid_compare (&td->max_election_id, &sd->election_id) > 0); } /* *-------------------------------------------------------------------------- * * _mongoc_topology_description_set_max_set_version -- * * Remember that we've seen a new replica set version. Unconditionally * sets td->set_version to sd->set_version. * *-------------------------------------------------------------------------- */ static void _mongoc_topology_description_set_max_set_version ( mongoc_topology_description_t *td, mongoc_server_description_t *sd) { td->max_set_version = sd->set_version; } /* *-------------------------------------------------------------------------- * * _mongoc_topology_description_set_max_election_id -- * * Remember that we've seen a new election id. Unconditionally sets * td->max_election_id to sd->election_id. * *-------------------------------------------------------------------------- */ static void _mongoc_topology_description_set_max_election_id ( mongoc_topology_description_t *td, mongoc_server_description_t *sd) { bson_oid_copy (&sd->election_id, &td->max_election_id); } static bool _mongoc_topology_description_server_is_candidate ( mongoc_server_description_type_t desc_type, mongoc_read_mode_t read_mode, mongoc_topology_description_type_t topology_type) { switch ((int)topology_type) { case MONGOC_TOPOLOGY_SINGLE: switch ((int)desc_type) { case MONGOC_SERVER_STANDALONE: return true; default: return false; } case MONGOC_TOPOLOGY_RS_NO_PRIMARY: case MONGOC_TOPOLOGY_RS_WITH_PRIMARY: switch ((int)read_mode) { case MONGOC_READ_PRIMARY: switch ((int)desc_type) { case MONGOC_SERVER_POSSIBLE_PRIMARY: case MONGOC_SERVER_RS_PRIMARY: return true; default: return false; } case MONGOC_READ_SECONDARY: switch ((int)desc_type) { case MONGOC_SERVER_RS_SECONDARY: return true; default: return false; } default: switch ((int)desc_type) { case MONGOC_SERVER_POSSIBLE_PRIMARY: case MONGOC_SERVER_RS_PRIMARY: case MONGOC_SERVER_RS_SECONDARY: return true; default: return false; } } case MONGOC_TOPOLOGY_SHARDED: switch ((int)desc_type) { case MONGOC_SERVER_MONGOS: return true; default: return false; } default: return false; } } typedef struct _mongoc_suitable_data_t { mongoc_read_mode_t read_mode; mongoc_topology_description_type_t topology_type; mongoc_server_description_t *primary; /* OUT */ mongoc_server_description_t **candidates; /* OUT */ size_t candidates_len; /* OUT */ bool has_secondary; /* OUT */ } mongoc_suitable_data_t; static bool _mongoc_replica_set_read_suitable_cb (void *item, void *ctx) { mongoc_server_description_t *server = (mongoc_server_description_t *)item; mongoc_suitable_data_t *data = (mongoc_suitable_data_t *)ctx; if (_mongoc_topology_description_server_is_candidate (server->type, data->read_mode, data->topology_type)) { if (server->type == MONGOC_SERVER_RS_PRIMARY) { data->primary = server; if (data->read_mode == MONGOC_READ_PRIMARY || data->read_mode == MONGOC_READ_PRIMARY_PREFERRED) { /* we want a primary and we have one, done! */ return false; } } if (server->type == MONGOC_SERVER_RS_SECONDARY) { data->has_secondary = true; } /* add to our candidates */ data->candidates[data->candidates_len++] = server; } return true; } /* if any mongos are candidates, add them to the candidates array */ static bool _mongoc_find_suitable_mongos_cb (void *item, void *ctx) { mongoc_server_description_t *server = (mongoc_server_description_t *)item; mongoc_suitable_data_t *data = (mongoc_suitable_data_t *)ctx; if (_mongoc_topology_description_server_is_candidate (server->type, data->read_mode, data->topology_type)) { data->candidates[data->candidates_len++] = server; } return true; } /* *------------------------------------------------------------------------- * * mongoc_topology_description_suitable_servers -- * * Return an array of suitable server descriptions for this * operation and read preference. * * NOTE: this method should only be called while holding the mutex on * the owning topology object. * * Returns: * Array of server descriptions, or NULL upon failure. * * Side effects: * None. * *------------------------------------------------------------------------- */ void mongoc_topology_description_suitable_servers ( mongoc_array_t *set, /* OUT */ mongoc_ss_optype_t optype, mongoc_topology_description_t *topology, const mongoc_read_prefs_t *read_pref, size_t local_threshold_ms) { mongoc_suitable_data_t data; mongoc_server_description_t **candidates; mongoc_server_description_t *server; int64_t nearest = -1; int i; mongoc_read_mode_t read_mode = mongoc_read_prefs_get_mode(read_pref); candidates = (mongoc_server_description_t **)bson_malloc0(sizeof(*candidates) * topology->servers->items_len); data.read_mode = read_mode; data.topology_type = topology->type; data.primary = NULL; data.candidates = candidates; data.candidates_len = 0; data.has_secondary = false; /* Single server -- * Either it is suitable or it isn't */ if (topology->type == MONGOC_TOPOLOGY_SINGLE) { server = (mongoc_server_description_t *)mongoc_set_get_item (topology->servers, 0); if (_mongoc_topology_description_server_is_candidate (server->type, read_mode, topology->type)) { _mongoc_array_append_val (set, server); } goto DONE; } /* Replica sets -- * Find suitable servers based on read mode */ if (topology->type == MONGOC_TOPOLOGY_RS_NO_PRIMARY || topology->type == MONGOC_TOPOLOGY_RS_WITH_PRIMARY) { if (optype == MONGOC_SS_READ) { mongoc_set_for_each(topology->servers, _mongoc_replica_set_read_suitable_cb, &data); /* if we have a primary, it's a candidate, for some read modes we are done */ if (read_mode == MONGOC_READ_PRIMARY || read_mode == MONGOC_READ_PRIMARY_PREFERRED) { if (data.primary) { _mongoc_array_append_val (set, data.primary); goto DONE; } } if (! mongoc_server_description_filter_eligible (data.candidates, data.candidates_len, read_pref)) { if (read_mode == MONGOC_READ_NEAREST) { goto DONE; } else { data.has_secondary = false; } } if (data.has_secondary && (read_mode == MONGOC_READ_SECONDARY || read_mode == MONGOC_READ_SECONDARY_PREFERRED)) { /* secondary or secondary preferred and we have one. */ for (i = 0; i < data.candidates_len; i++) { if (candidates[i] && candidates[i]->type == MONGOC_SERVER_RS_PRIMARY) { candidates[i] = NULL; } } } else if (read_mode == MONGOC_READ_SECONDARY_PREFERRED && data.primary) { /* secondary preferred, but only the one primary is a candidate */ _mongoc_array_append_val (set, data.primary); goto DONE; } } else if (topology->type == MONGOC_TOPOLOGY_RS_WITH_PRIMARY) { /* includes optype == MONGOC_SS_WRITE as the exclusion of the above if */ mongoc_set_for_each(topology->servers, _mongoc_topology_description_has_primary_cb, &data.primary); if (data.primary) { _mongoc_array_append_val (set, data.primary); goto DONE; } } } /* Sharded clusters -- * All candidates in the latency window are suitable */ if (topology->type == MONGOC_TOPOLOGY_SHARDED) { mongoc_set_for_each (topology->servers, _mongoc_find_suitable_mongos_cb, &data); } /* Ways to get here: * - secondary read * - secondary preferred read * - primary_preferred and no primary read * - sharded anything * Find the nearest, then select within the window */ for (i = 0; i < data.candidates_len; i++) { if (candidates[i] && (nearest == -1 || nearest > candidates[i]->round_trip_time)) { nearest = candidates[i]->round_trip_time; } } for (i = 0; i < data.candidates_len; i++) { if (candidates[i] && (candidates[i]->round_trip_time <= nearest + local_threshold_ms)) { _mongoc_array_append_val (set, candidates[i]); } } DONE: bson_free (candidates); return; } /* *------------------------------------------------------------------------- * * mongoc_topology_description_select -- * * Return a server description of a node that is appropriate for * the given read preference and operation type. * * NOTE: this method simply attempts to select a server from the * current topology, it does not retry or trigger topology checks. * * NOTE: this method should only be called while holding the mutex on * the owning topology object. * * Returns: * Selected server description, or NULL upon failure. * * Side effects: * None. * *------------------------------------------------------------------------- */ mongoc_server_description_t * mongoc_topology_description_select (mongoc_topology_description_t *topology, mongoc_ss_optype_t optype, const mongoc_read_prefs_t *read_pref, int64_t local_threshold_ms) { mongoc_array_t suitable_servers; mongoc_server_description_t *sd = NULL; ENTRY; if (!topology->compatible) { /* TODO, should we return an error object here, or just treat as a case where there are no suitable servers? */ RETURN(NULL); } if (topology->type == MONGOC_TOPOLOGY_SINGLE) { sd = (mongoc_server_description_t *)mongoc_set_get_item (topology->servers, 0); if (sd->has_is_master) { RETURN(sd); } else { RETURN(NULL); } } _mongoc_array_init(&suitable_servers, sizeof(mongoc_server_description_t *)); mongoc_topology_description_suitable_servers(&suitable_servers, optype, topology, read_pref, local_threshold_ms); if (suitable_servers.len != 0) { sd = _mongoc_array_index(&suitable_servers, mongoc_server_description_t*, rand() % suitable_servers.len); } _mongoc_array_destroy (&suitable_servers); RETURN(sd); } /* *-------------------------------------------------------------------------- * * mongoc_topology_description_server_by_id -- * * Get the server description for @id, if that server is present * in @description. Otherwise, return NULL and fill out optional * @error. * * NOTE: In most cases, caller should create a duplicate of the * returned server description. Caller should hold the mutex on the * owning topology object while calling this method and while using * the returned reference. * * Returns: * A mongoc_server_description_t *, or NULL. * * Side effects: * Fills out optional @error if server not found. * *-------------------------------------------------------------------------- */ mongoc_server_description_t * mongoc_topology_description_server_by_id (mongoc_topology_description_t *description, uint32_t id, bson_error_t *error) { mongoc_server_description_t *sd; BSON_ASSERT (description); sd = (mongoc_server_description_t *)mongoc_set_get(description->servers, id); if (!sd) { bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_NOT_ESTABLISHED, "Could not find description for node %u", id); } return sd; } /* *-------------------------------------------------------------------------- * * _mongoc_topology_description_remove_server -- * * If present, remove this server from this topology description. * * Returns: * None. * * Side effects: * Removes the server description from topology and destroys it. * *-------------------------------------------------------------------------- */ static void _mongoc_topology_description_remove_server (mongoc_topology_description_t *description, mongoc_server_description_t *server) { BSON_ASSERT (description); BSON_ASSERT (server); mongoc_set_rm(description->servers, server->id); } typedef struct _mongoc_address_and_id_t { const char *address; /* IN */ bool found; /* OUT */ uint32_t id; /* OUT */ } mongoc_address_and_id_t; /* find the given server and stop iterating */ static bool _mongoc_topology_description_has_server_cb (void *item, void *ctx /* IN - OUT */) { mongoc_server_description_t *server = (mongoc_server_description_t *)item; mongoc_address_and_id_t *data = (mongoc_address_and_id_t *)ctx; if (strcasecmp (data->address, server->connection_address) == 0) { data->found = true; data->id = server->id; return false; } return true; } /* *-------------------------------------------------------------------------- * * _mongoc_topology_description_has_set_version -- * * Whether @topology's max replica set version has been set. * * Returns: * True if the max setVersion was ever set. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static bool _mongoc_topology_description_has_set_version (mongoc_topology_description_t *td) { return td->max_set_version != MONGOC_NO_SET_VERSION; } /* *-------------------------------------------------------------------------- * * _mongoc_topology_description_topology_has_server -- * * Return true if @server is in @topology. If so, place its id in * @id if given. * * Returns: * True if server is in topology, false otherwise. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static bool _mongoc_topology_description_has_server (mongoc_topology_description_t *description, const char *address, uint32_t *id /* OUT */) { mongoc_address_and_id_t data; BSON_ASSERT (description); BSON_ASSERT (address); data.address = address; data.found = false; mongoc_set_for_each (description->servers, _mongoc_topology_description_has_server_cb, &data); if (data.found && id) { *id = data.id; } return data.found; } typedef struct _mongoc_address_and_type_t { const char *address; mongoc_server_description_type_t type; } mongoc_address_and_type_t; static bool _mongoc_label_unknown_member_cb (void *item, void *ctx) { mongoc_server_description_t *server = (mongoc_server_description_t *)item; mongoc_address_and_type_t *data = (mongoc_address_and_type_t *)ctx; if (strcasecmp (server->connection_address, data->address) == 0 && server->type == MONGOC_SERVER_UNKNOWN) { mongoc_server_description_set_state(server, data->type); return false; } return true; } /* *-------------------------------------------------------------------------- * * _mongoc_topology_description_label_unknown_member -- * * Find the server description with the given @address and if its * type is UNKNOWN, set its type to @type. * * Returns: * None. * * Side effects: * None. * *-------------------------------------------------------------------------- */ static void _mongoc_topology_description_label_unknown_member (mongoc_topology_description_t *description, const char *address, mongoc_server_description_type_t type) { mongoc_address_and_type_t data; BSON_ASSERT (description); BSON_ASSERT (address); data.type = type; data.address = address; mongoc_set_for_each(description->servers, _mongoc_label_unknown_member_cb, &data); } /* *-------------------------------------------------------------------------- * * _mongoc_topology_description_set_state -- * * Change the state of this cluster and unblock things waiting * on a change of topology type. * * Returns: * None. * * Side effects: * Unblocks anything waiting on this description to change states. * *-------------------------------------------------------------------------- */ static void _mongoc_topology_description_set_state (mongoc_topology_description_t *description, mongoc_topology_description_type_t type) { description->type = type; } static void _update_rs_type (mongoc_topology_description_t *topology) { if (_mongoc_topology_description_has_primary(topology)) { _mongoc_topology_description_set_state(topology, MONGOC_TOPOLOGY_RS_WITH_PRIMARY); } else { _mongoc_topology_description_set_state(topology, MONGOC_TOPOLOGY_RS_NO_PRIMARY); } } /* *-------------------------------------------------------------------------- * * _mongoc_topology_description_check_if_has_primary -- * * If there is a primary in topology, set topology * type to RS_WITH_PRIMARY, otherwise set it to * RS_NO_PRIMARY. * * Returns: * None. * * Side effects: * Changes the topology type. * *-------------------------------------------------------------------------- */ static void _mongoc_topology_description_check_if_has_primary (mongoc_topology_description_t *topology, mongoc_server_description_t *server) { _update_rs_type (topology); } /* *-------------------------------------------------------------------------- * * mongoc_topology_description_invalidate_server -- * * Invalidate a server if a network error occurred while using it in * another part of the client. Server description is set to type * UNKNOWN and other parameters are reset to defaults. * * NOTE: this method should only be called while holding the mutex on * the owning topology object. * *-------------------------------------------------------------------------- */ void mongoc_topology_description_invalidate_server (mongoc_topology_description_t *topology, uint32_t id) { mongoc_server_description_t *sd; bson_error_t error; sd = mongoc_topology_description_server_by_id (topology, id, NULL); mongoc_topology_description_handle_ismaster (topology, sd, NULL, 0, &error); return; } /* *-------------------------------------------------------------------------- * * mongoc_topology_description_add_server -- * * Add the specified server to the cluster topology if it is not * already a member. If @id, place its id in @id. * * NOTE: this method should only be called while holding the mutex on * the owning topology object. * * Return: * True if the server was added or already existed in the topology, * false if an error occurred. * * Side effects: * None. * *-------------------------------------------------------------------------- */ bool mongoc_topology_description_add_server (mongoc_topology_description_t *topology, const char *server, uint32_t *id /* OUT */) { uint32_t server_id; mongoc_server_description_t *description; BSON_ASSERT (topology); BSON_ASSERT (server); if (!_mongoc_topology_description_has_server(topology, server, &server_id)){ /* TODO this might not be an accurate count in all cases */ server_id = ++topology->max_server_id; description = (mongoc_server_description_t *)bson_malloc0(sizeof *description); mongoc_server_description_init(description, server, server_id); mongoc_set_add(topology->servers, server_id, description); } if (id) { *id = server_id; } return true; } static void _mongoc_topology_description_add_new_servers ( mongoc_topology_description_t *topology, mongoc_server_description_t *server) { bson_iter_t member_iter; const bson_t *rs_members[3]; int i; rs_members[0] = &server->hosts; rs_members[1] = &server->arbiters; rs_members[2] = &server->passives; for (i = 0; i < 3; i++) { bson_iter_init (&member_iter, rs_members[i]); while (bson_iter_next (&member_iter)) { mongoc_topology_description_add_server(topology, bson_iter_utf8(&member_iter, NULL), NULL); } } } typedef struct _mongoc_primary_and_topology_t { mongoc_topology_description_t *topology; mongoc_server_description_t *primary; } mongoc_primary_and_topology_t; /* invalidate old primaries */ static bool _mongoc_topology_description_invalidate_primaries_cb (void *item, void *ctx) { mongoc_server_description_t *server = (mongoc_server_description_t *)item; mongoc_primary_and_topology_t *data = (mongoc_primary_and_topology_t *)ctx; if (server->id != data->primary->id && server->type == MONGOC_SERVER_RS_PRIMARY) { mongoc_server_description_set_state (server, MONGOC_SERVER_UNKNOWN); mongoc_server_description_set_set_version (server, MONGOC_NO_SET_VERSION); mongoc_server_description_set_election_id (server, NULL); } return true; } /* Remove and destroy all replica set members not in primary's hosts lists */ static void _mongoc_topology_description_remove_unreported_servers ( mongoc_topology_description_t *topology, mongoc_server_description_t *primary) { mongoc_array_t to_remove; int i; mongoc_server_description_t *member; const char *address; _mongoc_array_init (&to_remove, sizeof (mongoc_server_description_t *)); /* Accumulate servers to be removed - do this before calling * _mongoc_topology_description_remove_server, which could call * mongoc_server_description_cleanup on the primary itself if it * doesn't report its own connection_address in its hosts list. * See hosts_differ_from_seeds.json */ for (i = 0; i < topology->servers->items_len; i++) { member = (mongoc_server_description_t *)mongoc_set_get_item (topology->servers, i); address = member->connection_address; if (!mongoc_server_description_has_rs_member(primary, address)) { _mongoc_array_append_val (&to_remove, member); } } /* now it's safe to call _mongoc_topology_description_remove_server, * even on the primary */ for (i = 0; i < to_remove.len; i++) { member = _mongoc_array_index ( &to_remove, mongoc_server_description_t *, i); _mongoc_topology_description_remove_server (topology, member); } _mongoc_array_destroy (&to_remove); } /* *-------------------------------------------------------------------------- * * _mongoc_topology_description_matches_me -- * * Server Discovery And Monitoring Spec: "Removal from the topology of * seed list members where the "me" property does not match the address * used to connect prevents clients from being able to select a server, * only to fail to re-select that server once the primary has responded. * * Returns: * True if "me" matches "connection_address". * * Side Effects: * None. * *-------------------------------------------------------------------------- */ static bool _mongoc_topology_description_matches_me (mongoc_server_description_t *server) { BSON_ASSERT (server->connection_address); if (!server->me) { /* "me" is unknown: consider it a match */ return true; } return strcasecmp (server->connection_address, server->me) == 0; } /* *-------------------------------------------------------------------------- * * _mongoc_update_rs_from_primary -- * * First, determine that this is really the primary: * -If this node isn't in the cluster, do nothing. * -If the cluster's set name is null, set it to node's set name. * Otherwise if the cluster's set name is different from node's, * we found a rogue primary, so remove it from the cluster and * check the cluster for a primary, then return. * -If any of the members of cluster reports an address different * from node's, node cannot be the primary. * Now that we know this is the primary: * -If any hosts, passives, or arbiters in node's description aren't * in the cluster, add them as UNKNOWN servers. * -If the cluster has any servers that aren't in node's description, * remove and destroy them. * Finally, check the cluster for the new primary. * * Returns: * None. * * Side effects: * Changes to the cluster, possible removal of cluster nodes. * *-------------------------------------------------------------------------- */ static void _mongoc_topology_description_update_rs_from_primary (mongoc_topology_description_t *topology, mongoc_server_description_t *server) { mongoc_primary_and_topology_t data; BSON_ASSERT (topology); BSON_ASSERT (server); if (!_mongoc_topology_description_has_server(topology, server->connection_address, NULL)) return; /* If server->set_name was null this function wouldn't be called from * mongoc_server_description_handle_ismaster(). static code analyzers however * don't know that so we check for it explicitly. */ if (server->set_name) { /* 'Server' can only be the primary if it has the right rs name */ if (!topology->set_name) { topology->set_name = bson_strdup (server->set_name); } else if (strcmp(topology->set_name, server->set_name) != 0) { _mongoc_topology_description_remove_server(topology, server); _update_rs_type (topology); return; } } if (mongoc_server_description_has_set_version (server) && mongoc_server_description_has_election_id (server)) { /* Server Discovery And Monitoring Spec: "The client remembers the * greatest electionId reported by a primary, and distrusts primaries * with lesser electionIds. This prevents the client from oscillating * between the old and new primary during a split-brain period." */ if (_mongoc_topology_description_later_election (topology, server)) { /* stale primary */ mongoc_topology_description_invalidate_server (topology, server->id); _update_rs_type (topology); return; } /* server's electionId >= topology's max electionId */ _mongoc_topology_description_set_max_election_id (topology, server); } if (mongoc_server_description_has_set_version (server) && (! _mongoc_topology_description_has_set_version (topology) || server->set_version > topology->max_set_version)) { _mongoc_topology_description_set_max_set_version (topology, server); } /* 'Server' is the primary! Invalidate other primaries if found */ data.primary = server; data.topology = topology; mongoc_set_for_each(topology->servers, _mongoc_topology_description_invalidate_primaries_cb, &data); /* Add to topology description any new servers primary knows about */ _mongoc_topology_description_add_new_servers (topology, server); /* Remove from topology description any servers primary doesn't know about */ _mongoc_topology_description_remove_unreported_servers (topology, server); /* Finally, set topology type */ _update_rs_type (topology); } /* *-------------------------------------------------------------------------- * * _mongoc_topology_description_update_rs_without_primary -- * * Update cluster's information when there is no primary. * * Returns: * None. * * Side Effects: * Alters cluster state, may remove node from cluster. * *-------------------------------------------------------------------------- */ static void _mongoc_topology_description_update_rs_without_primary (mongoc_topology_description_t *topology, mongoc_server_description_t *server) { BSON_ASSERT (topology); BSON_ASSERT (server); if (!_mongoc_topology_description_has_server(topology, server->connection_address, NULL)) { return; } /* make sure we're talking about the same replica set */ if (server->set_name) { if (!topology->set_name) { topology->set_name = bson_strdup(server->set_name); } else if (strcmp(topology->set_name, server->set_name)!= 0) { _mongoc_topology_description_remove_server(topology, server); return; } } /* Add new servers that this replica set member knows about */ _mongoc_topology_description_add_new_servers (topology, server); if (!_mongoc_topology_description_matches_me (server)) { _mongoc_topology_description_remove_server(topology, server); return; } /* If this server thinks there is a primary, label it POSSIBLE_PRIMARY */ if (server->current_primary) { _mongoc_topology_description_label_unknown_member(topology, server->current_primary, MONGOC_SERVER_POSSIBLE_PRIMARY); } } /* *-------------------------------------------------------------------------- * * _mongoc_topology_description_update_rs_with_primary_from_member -- * * Update cluster's information when there is a primary, but the * update is coming from another replica set member. * * Returns: * None. * * Side Effects: * Alters cluster state. * *-------------------------------------------------------------------------- */ static void _mongoc_topology_description_update_rs_with_primary_from_member (mongoc_topology_description_t *topology, mongoc_server_description_t *server) { BSON_ASSERT (topology); BSON_ASSERT (server); if (!_mongoc_topology_description_has_server(topology, server->connection_address, NULL)) { return; } /* set_name should never be null here */ if (strcmp(topology->set_name, server->set_name) != 0) { _mongoc_topology_description_remove_server(topology, server); _update_rs_type (topology); return; } if (!_mongoc_topology_description_matches_me (server)) { _mongoc_topology_description_remove_server(topology, server); return; } /* If there is no primary, label server's current_primary as the POSSIBLE_PRIMARY */ if (!_mongoc_topology_description_has_primary(topology) && server->current_primary) { _mongoc_topology_description_set_state(topology, MONGOC_TOPOLOGY_RS_NO_PRIMARY); _mongoc_topology_description_label_unknown_member(topology, server->current_primary, MONGOC_SERVER_POSSIBLE_PRIMARY); } } /* *-------------------------------------------------------------------------- * * _mongoc_topology_description_set_topology_type_to_sharded -- * * Sets topology's type to SHARDED. * * Returns: * None * * Side effects: * Alter's topology's type * *-------------------------------------------------------------------------- */ static void _mongoc_topology_description_set_topology_type_to_sharded (mongoc_topology_description_t *topology, mongoc_server_description_t *server) { _mongoc_topology_description_set_state(topology, MONGOC_TOPOLOGY_SHARDED); } /* *-------------------------------------------------------------------------- * * _mongoc_topology_description_transition_unknown_to_rs_no_primary -- * * Encapsulates transition from cluster state UNKNOWN to * RS_NO_PRIMARY. Sets the type to RS_NO_PRIMARY, * then updates the replica set accordingly. * * Returns: * None. * * Side effects: * Changes topology state. * *-------------------------------------------------------------------------- */ static void _mongoc_topology_description_transition_unknown_to_rs_no_primary (mongoc_topology_description_t *topology, mongoc_server_description_t *server) { _mongoc_topology_description_set_state(topology, MONGOC_TOPOLOGY_RS_NO_PRIMARY); _mongoc_topology_description_update_rs_without_primary(topology, server); } /* *-------------------------------------------------------------------------- * * _mongoc_topology_description_remove_and_check_primary -- * * Remove the server and check if the topology still has a primary. * * Returns: * None. * * Side effects: * Removes server from topology and destroys it. * *-------------------------------------------------------------------------- */ static void _mongoc_topology_description_remove_and_check_primary (mongoc_topology_description_t *topology, mongoc_server_description_t *server) { _mongoc_topology_description_remove_server(topology, server); _update_rs_type (topology); } /* *-------------------------------------------------------------------------- * * _mongoc_topology_description_update_unknown_with_standalone -- * * If the cluster doesn't contain this server, do nothing. * Otherwise, if the topology only has one seed, change its * type to SINGLE. If the topology has multiple seeds, it does not * include us, so remove this server and destroy it. * * Returns: * None. * * Side effects: * Changes the topology type, might remove server from topology. * *-------------------------------------------------------------------------- */ static void _mongoc_topology_description_update_unknown_with_standalone (mongoc_topology_description_t *topology, mongoc_server_description_t *server) { BSON_ASSERT (topology); BSON_ASSERT (server); if (!_mongoc_topology_description_has_server(topology, server->connection_address, NULL)) return; if (topology->servers->items_len > 1) { /* This cluster contains other servers, it cannot be a standalone. */ _mongoc_topology_description_remove_server(topology, server); } else { _mongoc_topology_description_set_state(topology, MONGOC_TOPOLOGY_SINGLE); } } /* *-------------------------------------------------------------------------- * * This table implements the 'ToplogyType' table outlined in the Server * Discovery and Monitoring spec. Each row represents a server type, * and each column represents the topology type. Given a current topology * type T and a newly-observed server type S, use the function at * state_transions[S][T] to transition to a new state. * * Rows should be read like so: * { server type for this row * UNKNOWN, * SHARDED, * RS_NO_PRIMARY, * RS_WITH_PRIMARY * } * *-------------------------------------------------------------------------- */ typedef void (*transition_t)(mongoc_topology_description_t *topology, mongoc_server_description_t *server); transition_t gSDAMTransitionTable[MONGOC_SERVER_DESCRIPTION_TYPES][MONGOC_TOPOLOGY_DESCRIPTION_TYPES] = { { /* UNKNOWN */ NULL, /* MONGOC_TOPOLOGY_UNKNOWN */ NULL, /* MONGOC_TOPOLOGY_SHARDED */ NULL, /* MONGOC_TOPOLOGY_RS_NO_PRIMARY */ _mongoc_topology_description_check_if_has_primary /* MONGOC_TOPOLOGY_RS_WITH_PRIMARY */ }, { /* STANDALONE */ _mongoc_topology_description_update_unknown_with_standalone, _mongoc_topology_description_remove_server, _mongoc_topology_description_remove_server, _mongoc_topology_description_remove_and_check_primary }, { /* MONGOS */ _mongoc_topology_description_set_topology_type_to_sharded, NULL, _mongoc_topology_description_remove_server, _mongoc_topology_description_remove_and_check_primary }, { /* POSSIBLE_PRIMARY */ NULL, NULL, NULL, NULL }, { /* PRIMARY */ _mongoc_topology_description_update_rs_from_primary, _mongoc_topology_description_remove_server, _mongoc_topology_description_update_rs_from_primary, _mongoc_topology_description_update_rs_from_primary }, { /* SECONDARY */ _mongoc_topology_description_transition_unknown_to_rs_no_primary, _mongoc_topology_description_remove_server, _mongoc_topology_description_update_rs_without_primary, _mongoc_topology_description_update_rs_with_primary_from_member }, { /* ARBITER */ _mongoc_topology_description_transition_unknown_to_rs_no_primary, _mongoc_topology_description_remove_server, _mongoc_topology_description_update_rs_without_primary, _mongoc_topology_description_update_rs_with_primary_from_member }, { /* RS_OTHER */ _mongoc_topology_description_transition_unknown_to_rs_no_primary, _mongoc_topology_description_remove_server, _mongoc_topology_description_update_rs_without_primary, _mongoc_topology_description_update_rs_with_primary_from_member }, { /* RS_GHOST */ NULL, _mongoc_topology_description_remove_server, NULL, _mongoc_topology_description_check_if_has_primary } }; /* *-------------------------------------------------------------------------- * * mongoc_topology_description_handle_ismaster -- * * Handle an ismaster. This is called by the background SDAM process, * and by client when invalidating servers. * * NOTE: this method should only be called while holding the mutex on * the owning topology object. * *-------------------------------------------------------------------------- */ void mongoc_topology_description_handle_ismaster ( mongoc_topology_description_t *topology, mongoc_server_description_t *sd, const bson_t *ismaster_response, int64_t rtt_msec, bson_error_t *error) { BSON_ASSERT (topology); BSON_ASSERT (sd); if (!_mongoc_topology_description_has_server (topology, sd->connection_address, NULL)) { MONGOC_DEBUG("Couldn't find %s in Topology Description", sd->connection_address); return; } mongoc_server_description_handle_ismaster (sd, ismaster_response, rtt_msec, error); if (gSDAMTransitionTable[sd->type][topology->type]) { TRACE("Transitioning to %d for %d", topology->type, sd->type); gSDAMTransitionTable[sd->type][topology->type] (topology, sd); } else { TRACE("No transition entry to %d for %d", topology->type, sd->type); } } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-topology-private.h0000664000175000017500000000740212673034026024577 0ustar jmikolajmikola/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_TOPOLOGY_PRIVATE_H #define MONGOC_TOPOLOGY_PRIVATE_H #include "mongoc-read-prefs-private.h" #include "mongoc-topology-scanner-private.h" #include "mongoc-server-description-private.h" #include "mongoc-topology-description-private.h" #include "mongoc-thread-private.h" #include "mongoc-uri.h" #define MONGOC_TOPOLOGY_MIN_HEARTBEAT_FREQUENCY_MS 500 #define MONGOC_TOPOLOGY_SOCKET_CHECK_INTERVAL_MS 5000 #define MONGOC_TOPOLOGY_COOLDOWN_MS 5000 #define MONGOC_TOPOLOGY_SERVER_SELECTION_TIMEOUT_MS 30000 #define MONGOC_TOPOLOGY_HEARTBEAT_FREQUENCY_MS_MULTI_THREADED 10000 #define MONGOC_TOPOLOGY_HEARTBEAT_FREQUENCY_MS_SINGLE_THREADED 60000 typedef enum { MONGOC_TOPOLOGY_BG_OFF, MONGOC_TOPOLOGY_BG_RUNNING, MONGOC_TOPOLOGY_BG_SHUTTING_DOWN, } mongoc_topology_bg_state_t; typedef struct _mongoc_topology_t { mongoc_topology_description_t description; mongoc_uri_t *uri; mongoc_topology_scanner_t *scanner; bool server_selection_try_once; int64_t last_scan; int64_t connect_timeout_msec; int64_t server_selection_timeout_msec; int64_t heartbeat_msec; mongoc_mutex_t mutex; mongoc_cond_t cond_client; mongoc_cond_t cond_server; mongoc_thread_t thread; mongoc_topology_bg_state_t bg_thread_state; bool scan_requested; bool scanning; bool got_ismaster; bool shutdown_requested; bool single_threaded; bool stale; } mongoc_topology_t; mongoc_topology_t * mongoc_topology_new (const mongoc_uri_t *uri, bool single_threaded); void mongoc_topology_destroy (mongoc_topology_t *topology); mongoc_server_description_t * mongoc_topology_select (mongoc_topology_t *topology, mongoc_ss_optype_t optype, const mongoc_read_prefs_t *read_prefs, int64_t local_threshold_msec, bson_error_t *error); mongoc_server_description_t * mongoc_topology_server_by_id (mongoc_topology_t *topology, uint32_t id, bson_error_t *error); bool mongoc_topology_get_server_type (mongoc_topology_t *topology, uint32_t id, mongoc_topology_description_type_t *topology_type, mongoc_server_description_type_t *server_type, bson_error_t *error); void mongoc_topology_request_scan (mongoc_topology_t *topology); void mongoc_topology_invalidate_server (mongoc_topology_t *topology, uint32_t id); int64_t mongoc_topology_server_timestamp (mongoc_topology_t *topology, uint32_t id); #endif mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-topology-scanner-private.h0000664000175000017500000001234312673034026026226 0ustar jmikolajmikola/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_TOPOLOGY_SCANNER_PRIVATE_H #define MONGOC_TOPOLOGY_SCANNER_PRIVATE_H /* TODO: rename to TOPOLOGY scanner */ #if !defined (MONGOC_I_AM_A_DRIVER) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #include #include "mongoc-async-private.h" #include "mongoc-async-cmd-private.h" #include "mongoc-host-list.h" BSON_BEGIN_DECLS typedef void (*mongoc_topology_scanner_cb_t)(uint32_t id, const bson_t *bson, int64_t rtt, void *data, bson_error_t *error); struct mongoc_topology_scanner; typedef struct mongoc_topology_scanner_node { uint32_t id; mongoc_async_cmd_t *cmd; mongoc_stream_t *stream; int64_t timestamp; int64_t last_used; int64_t last_failed; bool has_auth; mongoc_host_list_t host; struct addrinfo *dns_results; struct addrinfo *current_dns_result; struct mongoc_topology_scanner *ts; struct mongoc_topology_scanner_node *next; struct mongoc_topology_scanner_node *prev; bool retired; bson_error_t last_error; } mongoc_topology_scanner_node_t; typedef struct mongoc_topology_scanner { mongoc_async_t *async; mongoc_topology_scanner_node_t *nodes; uint32_t seq; bson_t ismaster_cmd; mongoc_topology_scanner_cb_t cb; void *cb_data; bool in_progress; const mongoc_uri_t *uri; mongoc_async_cmd_setup_t setup; mongoc_stream_initiator_t initiator; void *initiator_context; #ifdef MONGOC_ENABLE_SSL mongoc_ssl_opt_t *ssl_opts; #endif } mongoc_topology_scanner_t; mongoc_topology_scanner_t * mongoc_topology_scanner_new (const mongoc_uri_t *uri, mongoc_topology_scanner_cb_t cb, void *data); void mongoc_topology_scanner_destroy (mongoc_topology_scanner_t *ts); mongoc_topology_scanner_node_t * mongoc_topology_scanner_add (mongoc_topology_scanner_t *ts, const mongoc_host_list_t *host, uint32_t id); void mongoc_topology_scanner_add_and_scan (mongoc_topology_scanner_t *ts, const mongoc_host_list_t *host, uint32_t id, int64_t timeout_msec); void mongoc_topology_scanner_node_retire (mongoc_topology_scanner_node_t *node); void mongoc_topology_scanner_node_disconnect (mongoc_topology_scanner_node_t *node, bool failed); void mongoc_topology_scanner_node_destroy (mongoc_topology_scanner_node_t *node, bool failed); void mongoc_topology_scanner_start (mongoc_topology_scanner_t *ts, int32_t timeout_msec, bool obey_cooldown); bool mongoc_topology_scanner_work (mongoc_topology_scanner_t *ts, int32_t timeout_msec); void mongoc_topology_scanner_sum_errors (mongoc_topology_scanner_t *ts, bson_error_t *error); void mongoc_topology_scanner_reset (mongoc_topology_scanner_t *ts); bool mongoc_topology_scanner_node_setup (mongoc_topology_scanner_node_t *node, bson_error_t *error); mongoc_topology_scanner_node_t * mongoc_topology_scanner_get_node (mongoc_topology_scanner_t *ts, uint32_t id); bool mongoc_topology_scanner_has_node_for_host (mongoc_topology_scanner_t *ts, mongoc_host_list_t *host); void mongoc_topology_scanner_set_stream_initiator (mongoc_topology_scanner_t *ts, mongoc_stream_initiator_t si, void *ctx); #ifdef MONGOC_ENABLE_SSL void mongoc_topology_scanner_set_ssl_opts (mongoc_topology_scanner_t *ts, mongoc_ssl_opt_t *opts); #endif BSON_END_DECLS #endif /* MONGOC_TOPOLOGY_SCANNER_PRIVATE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-topology-scanner.c0000664000175000017500000004376012673034026024560 0ustar jmikolajmikola/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include "mongoc-error.h" #include "mongoc-trace.h" #include "mongoc-topology-scanner-private.h" #include "mongoc-stream-socket.h" #ifdef MONGOC_ENABLE_SSL #include "mongoc-stream-tls.h" #endif #include "mongoc-counters-private.h" #include "utlist.h" #include "mongoc-topology-private.h" #include "mongoc-host-list-private.h" #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "topology_scanner" static void mongoc_topology_scanner_ismaster_handler (mongoc_async_cmd_result_t async_status, const bson_t *ismaster_response, int64_t rtt_msec, void *data, bson_error_t *error); mongoc_topology_scanner_t * mongoc_topology_scanner_new (const mongoc_uri_t *uri, mongoc_topology_scanner_cb_t cb, void *data) { mongoc_topology_scanner_t *ts = (mongoc_topology_scanner_t *)bson_malloc0 (sizeof (*ts)); ts->async = mongoc_async_new (); bson_init (&ts->ismaster_cmd); BSON_APPEND_INT32 (&ts->ismaster_cmd, "isMaster", 1); ts->cb = cb; ts->cb_data = data; ts->uri = uri; return ts; } #ifdef MONGOC_ENABLE_SSL void mongoc_topology_scanner_set_ssl_opts (mongoc_topology_scanner_t *ts, mongoc_ssl_opt_t *opts) { ts->ssl_opts = opts; ts->setup = mongoc_async_cmd_tls_setup; } #endif void mongoc_topology_scanner_set_stream_initiator (mongoc_topology_scanner_t *ts, mongoc_stream_initiator_t si, void *ctx) { ts->initiator = si; ts->initiator_context = ctx; ts->setup = NULL; } void mongoc_topology_scanner_destroy (mongoc_topology_scanner_t *ts) { mongoc_topology_scanner_node_t *ele, *tmp; DL_FOREACH_SAFE (ts->nodes, ele, tmp) { mongoc_topology_scanner_node_destroy (ele, false); } mongoc_async_destroy (ts->async); bson_destroy (&ts->ismaster_cmd); bson_free (ts); } mongoc_topology_scanner_node_t * mongoc_topology_scanner_add (mongoc_topology_scanner_t *ts, const mongoc_host_list_t *host, uint32_t id) { mongoc_topology_scanner_node_t *node; node = (mongoc_topology_scanner_node_t *) bson_malloc0 (sizeof (*node)); memcpy (&node->host, host, sizeof (*host)); node->id = id; node->ts = ts; node->last_failed = -1; DL_APPEND(ts->nodes, node); return node; } void mongoc_topology_scanner_add_and_scan (mongoc_topology_scanner_t *ts, const mongoc_host_list_t *host, uint32_t id, int64_t timeout_msec) { mongoc_topology_scanner_node_t *node; BSON_ASSERT (timeout_msec < INT32_MAX); node = mongoc_topology_scanner_add (ts, host, id); /* begin non-blocking connection, don't wait for success */ if (node && mongoc_topology_scanner_node_setup (node, &node->last_error)) { node->cmd = mongoc_async_cmd ( ts->async, node->stream, ts->setup, node->host.host, "admin", &ts->ismaster_cmd, &mongoc_topology_scanner_ismaster_handler, node, (int32_t) timeout_msec); } /* if setup fails the node stays in the scanner. destroyed after the scan. */ return; } void mongoc_topology_scanner_node_retire (mongoc_topology_scanner_node_t *node) { if (node->cmd) { node->cmd->state = MONGOC_ASYNC_CMD_CANCELED_STATE; } node->retired = true; } void mongoc_topology_scanner_node_disconnect (mongoc_topology_scanner_node_t *node, bool failed) { if (node->dns_results) { freeaddrinfo (node->dns_results); node->dns_results = NULL; node->current_dns_result = NULL; } if (node->cmd) { mongoc_async_cmd_destroy (node->cmd); node->cmd = NULL; } if (node->stream) { if (failed) { mongoc_stream_failed (node->stream); } else { mongoc_stream_destroy (node->stream); } node->stream = NULL; } } void mongoc_topology_scanner_node_destroy (mongoc_topology_scanner_node_t *node, bool failed) { DL_DELETE (node->ts->nodes, node); mongoc_topology_scanner_node_disconnect (node, failed); bson_free (node); } /* *-------------------------------------------------------------------------- * * mongoc_topology_scanner_get_node -- * * Return the scanner node with the given id. * * NOTE: only use this method when single-threaded! * *-------------------------------------------------------------------------- */ mongoc_topology_scanner_node_t * mongoc_topology_scanner_get_node (mongoc_topology_scanner_t *ts, uint32_t id) { mongoc_topology_scanner_node_t *ele, *tmp; DL_FOREACH_SAFE (ts->nodes, ele, tmp) { if (ele->id == id) { return ele; } if (ele->id > id) { break; } } return NULL; } /* *-------------------------------------------------------------------------- * * mongoc_topology_scanner_has_node_for_host -- * * Whether the scanner has a node for the given host and port. * *-------------------------------------------------------------------------- */ bool mongoc_topology_scanner_has_node_for_host (mongoc_topology_scanner_t *ts, mongoc_host_list_t *host) { mongoc_topology_scanner_node_t *ele, *tmp; DL_FOREACH_SAFE (ts->nodes, ele, tmp) { if (_mongoc_host_list_equal (&ele->host, host)) { return true; } } return false; } /* *----------------------------------------------------------------------- * * This is the callback passed to async_cmd when we're running * ismasters from within the topology monitor. * *----------------------------------------------------------------------- */ static void mongoc_topology_scanner_ismaster_handler (mongoc_async_cmd_result_t async_status, const bson_t *ismaster_response, int64_t rtt_msec, void *data, bson_error_t *error) { mongoc_topology_scanner_node_t *node; int64_t now; const char *message; BSON_ASSERT (data); node = (mongoc_topology_scanner_node_t *)data; node->cmd = NULL; if (node->retired) { return; } now = bson_get_monotonic_time (); /* if no ismaster response, async cmd had an error or timed out */ if (!ismaster_response || async_status == MONGOC_ASYNC_CMD_ERROR || async_status == MONGOC_ASYNC_CMD_TIMEOUT) { mongoc_stream_failed (node->stream); node->stream = NULL; node->last_failed = now; message = async_status == MONGOC_ASYNC_CMD_TIMEOUT ? "connection error" : "connection timeout"; bson_set_error (&node->last_error, MONGOC_ERROR_CLIENT, MONGOC_ERROR_STREAM_CONNECT, "%s calling ismaster on \'%s\'", message, node->host.host_and_port); } else { node->last_failed = -1; } node->last_used = now; node->ts->cb (node->id, ismaster_response, rtt_msec, node->ts->cb_data, error); } /* *-------------------------------------------------------------------------- * * mongoc_topology_scanner_node_connect_tcp -- * * Create a socket stream for this node, begin a non-blocking * connect and return. * * Returns: * A stream. On failure, return NULL and fill out the error. * *-------------------------------------------------------------------------- */ static mongoc_stream_t * mongoc_topology_scanner_node_connect_tcp (mongoc_topology_scanner_node_t *node, bson_error_t *error) { mongoc_socket_t *sock = NULL; struct addrinfo hints; struct addrinfo *rp; char portstr [8]; mongoc_host_list_t *host; int s; ENTRY; host = &node->host; if (!node->dns_results) { bson_snprintf (portstr, sizeof portstr, "%hu", host->port); memset (&hints, 0, sizeof hints); hints.ai_family = host->family; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = 0; hints.ai_protocol = 0; s = getaddrinfo (host->host, portstr, &hints, &node->dns_results); if (s != 0) { mongoc_counter_dns_failure_inc (); bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_NAME_RESOLUTION, "Failed to resolve '%s'", host->host); RETURN (NULL); } node->current_dns_result = node->dns_results; mongoc_counter_dns_success_inc (); } for (; node->current_dns_result; node->current_dns_result = node->current_dns_result->ai_next) { rp = node->current_dns_result; /* * Create a new non-blocking socket. */ if (!(sock = mongoc_socket_new (rp->ai_family, rp->ai_socktype, rp->ai_protocol))) { continue; } mongoc_socket_connect (sock, rp->ai_addr, (socklen_t)rp->ai_addrlen, 0); break; } if (!sock) { bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_CONNECT, "Failed to connect to target host: '%s'", host->host_and_port); freeaddrinfo (node->dns_results); node->dns_results = NULL; node->current_dns_result = NULL; RETURN (NULL); } return mongoc_stream_socket_new (sock); } static mongoc_stream_t * mongoc_topology_scanner_node_connect_unix (mongoc_topology_scanner_node_t *node, bson_error_t *error) { #ifdef _WIN32 ENTRY; bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_CONNECT, "UNIX domain sockets not supported on win32."); RETURN (NULL); #else struct sockaddr_un saddr; mongoc_socket_t *sock; mongoc_stream_t *ret = NULL; mongoc_host_list_t *host; ENTRY; host = &node->host; memset (&saddr, 0, sizeof saddr); saddr.sun_family = AF_UNIX; bson_snprintf (saddr.sun_path, sizeof saddr.sun_path - 1, "%s", host->host); sock = mongoc_socket_new (AF_UNIX, SOCK_STREAM, 0); if (sock == NULL) { bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_SOCKET, "Failed to create socket."); RETURN (NULL); } if (-1 == mongoc_socket_connect (sock, (struct sockaddr *)&saddr, sizeof saddr, -1)) { char buf[128]; char *errstr; errstr = bson_strerror_r(mongoc_socket_errno(sock), buf, sizeof(buf)); bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_CONNECT, "Failed to connect to UNIX domain socket: %s", errstr); mongoc_socket_destroy (sock); RETURN (NULL); } ret = mongoc_stream_socket_new (sock); RETURN (ret); #endif } /* *-------------------------------------------------------------------------- * * mongoc_topology_scanner_node_setup -- * * Create a stream and begin a non-blocking connect. * * Returns: * true on success, or false and error is set. * *-------------------------------------------------------------------------- */ bool mongoc_topology_scanner_node_setup (mongoc_topology_scanner_node_t *node, bson_error_t *error) { mongoc_stream_t *sock_stream; if (node->stream) { return true; } BSON_ASSERT (!node->retired); if (node->ts->initiator) { sock_stream = node->ts->initiator (node->ts->uri, &node->host, node->ts->initiator_context, error); } else { if (node->host.family == AF_UNIX) { sock_stream = mongoc_topology_scanner_node_connect_unix (node, error); } else { sock_stream = mongoc_topology_scanner_node_connect_tcp (node, error); } #ifdef MONGOC_ENABLE_SSL if (sock_stream && node->ts->ssl_opts) { sock_stream = mongoc_stream_tls_new (sock_stream, node->ts->ssl_opts, 1); } #endif } if (!sock_stream) { /* Pass a rtt of -1 if we couldn't initialize a stream in node_setup */ node->ts->cb (node->id, NULL, -1, node->ts->cb_data, error); return false; } node->stream = sock_stream; node->has_auth = false; node->timestamp = bson_get_monotonic_time (); return true; } /* *-------------------------------------------------------------------------- * * mongoc_topology_scanner_start -- * * Initializes the scanner and begins a full topology check. This * should be called once before calling mongoc_topology_scanner_work() * repeatedly to complete the scan. * * If "obey_cooldown" is true, this is a single-threaded blocking scan * that must obey the Server Discovery And Monitoring Spec's cooldownMS: * * "After a single-threaded client gets a network error trying to check * a server, the client skips re-checking the server until cooldownMS has * passed. * * "This avoids spending connectTimeoutMS on each unavailable server * during each scan. * * "This value MUST be 5000 ms, and it MUST NOT be configurable." * *-------------------------------------------------------------------------- */ void mongoc_topology_scanner_start (mongoc_topology_scanner_t *ts, int32_t timeout_msec, bool obey_cooldown) { mongoc_topology_scanner_node_t *node, *tmp; int64_t cooldown = INT64_MAX; BSON_ASSERT (ts); if (ts->in_progress) { return; } if (obey_cooldown) { /* when current cooldown period began */ cooldown = bson_get_monotonic_time () - 1000 * MONGOC_TOPOLOGY_COOLDOWN_MS; } DL_FOREACH_SAFE (ts->nodes, node, tmp) { /* check node if it last failed before current cooldown period began */ if (node->last_failed < cooldown) { if (mongoc_topology_scanner_node_setup (node, &node->last_error)) { BSON_ASSERT (!node->cmd); node->cmd = mongoc_async_cmd ( ts->async, node->stream, ts->setup, node->host.host, "admin", &ts->ismaster_cmd, &mongoc_topology_scanner_ismaster_handler, node, timeout_msec); } } } } /* *-------------------------------------------------------------------------- * * mongoc_topology_scanner_work -- * * Crank the knob on the topology scanner state machine. This should * be called only after mongoc_topology_scanner_start() has been used * to begin the scan. * * Returns: * true if there is more work to do, false if scan is done. * *-------------------------------------------------------------------------- */ bool mongoc_topology_scanner_work (mongoc_topology_scanner_t *ts, int32_t timeout_msec) { bool r; r = mongoc_async_run (ts->async, timeout_msec); if (! r) { ts->in_progress = false; } return r; } /* *-------------------------------------------------------------------------- * * mongoc_topology_scanner_sum_errors -- * * Summarizes all scanner node errors into one error message * *-------------------------------------------------------------------------- */ void mongoc_topology_scanner_sum_errors (mongoc_topology_scanner_t *ts, bson_error_t *error) { mongoc_topology_scanner_node_t *node, *tmp; DL_FOREACH_SAFE (ts->nodes, node, tmp) { if (node->last_error.code) { char *msg = NULL; if (error->code) { msg = bson_strdup(error->message); } bson_set_error(error, MONGOC_ERROR_SERVER_SELECTION, MONGOC_ERROR_SERVER_SELECTION_FAILURE, "%s[%s] ", msg ? msg : "", node->last_error.message); if (msg) { bson_free (msg); } } } if (error->code) { error->message[strlen(error->message)-1] = '\0'; } } /* *-------------------------------------------------------------------------- * * mongoc_topology_scanner_reset -- * * Reset "retired" nodes that failed or were removed in the previous * scan. * *-------------------------------------------------------------------------- */ void mongoc_topology_scanner_reset (mongoc_topology_scanner_t *ts) { mongoc_topology_scanner_node_t *node, *tmp; DL_FOREACH_SAFE (ts->nodes, node, tmp) { if (node->retired) { mongoc_topology_scanner_node_destroy (node, true); } } } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-topology.c0000664000175000017500000007127312673034026023131 0ustar jmikolajmikola/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "mongoc-error.h" #include "mongoc-topology-private.h" #include "mongoc-uri-private.h" #include "mongoc-util-private.h" #include "utlist.h" static void _mongoc_topology_background_thread_stop (mongoc_topology_t *topology); static void _mongoc_topology_background_thread_start (mongoc_topology_t *topology); static void _mongoc_topology_request_scan (mongoc_topology_t *topology); static bool _mongoc_topology_reconcile_add_nodes (void *item, void *ctx) { mongoc_server_description_t *sd = item; mongoc_topology_t *topology = (mongoc_topology_t *)ctx; mongoc_topology_scanner_t *scanner = topology->scanner; /* quickly search by id, then check if a node for this host was retired in * this scan. */ if (! mongoc_topology_scanner_get_node (scanner, sd->id) && ! mongoc_topology_scanner_has_node_for_host (scanner, &sd->host)) { mongoc_topology_scanner_add_and_scan (scanner, &sd->host, sd->id, topology->connect_timeout_msec); } return true; } void mongoc_topology_reconcile (mongoc_topology_t *topology) { mongoc_topology_scanner_node_t *ele, *tmp; mongoc_topology_description_t *description; mongoc_topology_scanner_t *scanner; description = &topology->description; scanner = topology->scanner; /* Add newly discovered nodes */ mongoc_set_for_each(description->servers, _mongoc_topology_reconcile_add_nodes, topology); /* Remove removed nodes */ DL_FOREACH_SAFE (scanner->nodes, ele, tmp) { if (!mongoc_topology_description_server_by_id (description, ele->id, NULL)) { mongoc_topology_scanner_node_retire (ele); } } } /* *------------------------------------------------------------------------- * * _mongoc_topology_scanner_cb -- * * Callback method to handle ismaster responses received by async * command objects. * * NOTE: This method locks the given topology's mutex. * *------------------------------------------------------------------------- */ void _mongoc_topology_scanner_cb (uint32_t id, const bson_t *ismaster_response, int64_t rtt_msec, void *data, bson_error_t *error) { mongoc_topology_t *topology; mongoc_server_description_t *sd; BSON_ASSERT (data); topology = (mongoc_topology_t *)data; if (rtt_msec >= 0) { /* If the scanner failed to create a socket for this server, that means * we're in scanner_start, which means we're under the mutex. So don't * take the mutex for rtt < 0 */ mongoc_mutex_lock (&topology->mutex); } sd = mongoc_topology_description_server_by_id (&topology->description, id, NULL); if (sd) { mongoc_topology_description_handle_ismaster (&topology->description, sd, ismaster_response, rtt_msec, error); /* The processing of the ismaster results above may have added/removed * server descriptions. We need to reconcile that with our monitoring agents */ mongoc_topology_reconcile(topology); /* TODO only wake up all clients if we found any topology changes */ mongoc_cond_broadcast (&topology->cond_client); } if (rtt_msec >= 0) { mongoc_mutex_unlock (&topology->mutex); } } /* *------------------------------------------------------------------------- * * mongoc_topology_new -- * * Creates and returns a new topology object. * * Returns: * A new topology object. * * Side effects: * None. * *------------------------------------------------------------------------- */ mongoc_topology_t * mongoc_topology_new (const mongoc_uri_t *uri, bool single_threaded) { mongoc_topology_t *topology; mongoc_topology_description_type_t init_type; uint32_t id; const mongoc_host_list_t *hl; BSON_ASSERT (uri); topology = (mongoc_topology_t *)bson_malloc0(sizeof *topology); /* * Not ideal, but there's no great way to do this. * Base on the URI, we assume: * - if we've got a replicaSet name, initialize to RS_NO_PRIMARY * - otherwise, if the seed list has a single host, initialize to SINGLE * - everything else gets initialized to UNKNOWN */ if (mongoc_uri_get_replica_set(uri)) { init_type = MONGOC_TOPOLOGY_RS_NO_PRIMARY; } else { hl = mongoc_uri_get_hosts(uri); if (hl->next) { init_type = MONGOC_TOPOLOGY_UNKNOWN; } else { init_type = MONGOC_TOPOLOGY_SINGLE; } } mongoc_topology_description_init(&topology->description, init_type); topology->description.set_name = bson_strdup(mongoc_uri_get_replica_set(uri)); topology->uri = mongoc_uri_copy (uri); topology->scanner = mongoc_topology_scanner_new (topology->uri, _mongoc_topology_scanner_cb, topology); topology->single_threaded = single_threaded; if (single_threaded) { /* Server Selection Spec: * * "Single-threaded drivers MUST provide a "serverSelectionTryOnce" * mode, in which the driver scans the topology exactly once after * server selection fails, then either selects a server or raises an * error. * * "The serverSelectionTryOnce option MUST be true by default." */ topology->server_selection_try_once = mongoc_uri_get_option_as_bool ( uri, "serverselectiontryonce", true); } else { topology->server_selection_try_once = false; } topology->server_selection_timeout_msec = mongoc_uri_get_option_as_int32( topology->uri, "serverselectiontimeoutms", MONGOC_TOPOLOGY_SERVER_SELECTION_TIMEOUT_MS); /* Total time allowed to check a server is connectTimeoutMS. * Server Discovery And Monitoring Spec: * * "The socket used to check a server MUST use the same connectTimeoutMS as * regular sockets. Multi-threaded clients SHOULD set monitoring sockets' * socketTimeoutMS to the connectTimeoutMS." */ topology->connect_timeout_msec = mongoc_uri_get_option_as_int32( topology->uri, "connecttimeoutms", MONGOC_DEFAULT_CONNECTTIMEOUTMS); topology->heartbeat_msec = mongoc_uri_get_option_as_int32( topology->uri, "heartbeatfrequencyms", (single_threaded ? MONGOC_TOPOLOGY_HEARTBEAT_FREQUENCY_MS_SINGLE_THREADED : MONGOC_TOPOLOGY_HEARTBEAT_FREQUENCY_MS_MULTI_THREADED) ); mongoc_mutex_init (&topology->mutex); mongoc_cond_init (&topology->cond_client); mongoc_cond_init (&topology->cond_server); for ( hl = mongoc_uri_get_hosts (uri); hl; hl = hl->next) { mongoc_topology_description_add_server (&topology->description, hl->host_and_port, &id); mongoc_topology_scanner_add (topology->scanner, hl, id); } if (! topology->single_threaded) { _mongoc_topology_background_thread_start (topology); } return topology; } /* *------------------------------------------------------------------------- * * mongoc_topology_destroy -- * * Free the memory associated with this topology object. * * Returns: * None. * * Side effects: * @topology will be cleaned up. * *------------------------------------------------------------------------- */ void mongoc_topology_destroy (mongoc_topology_t *topology) { if (!topology) { return; } _mongoc_topology_background_thread_stop (topology); mongoc_uri_destroy (topology->uri); mongoc_topology_description_destroy(&topology->description); mongoc_topology_scanner_destroy (topology->scanner); mongoc_cond_destroy (&topology->cond_client); mongoc_cond_destroy (&topology->cond_server); mongoc_mutex_destroy (&topology->mutex); bson_free(topology); } /* *-------------------------------------------------------------------------- * * _mongoc_topology_run_scanner -- * * Not threadsafe, the expectation is that we're either single * threaded or only the background thread runs scans. * * Crank the underlying scanner until we've timed out or finished. * * Returns: * true if there is more work to do, false otherwise * *-------------------------------------------------------------------------- */ static bool _mongoc_topology_run_scanner (mongoc_topology_t *topology, int64_t work_msec) { int64_t now; int64_t expire_at; bool keep_going = true; now = bson_get_monotonic_time (); expire_at = now + (work_msec * 1000); /* while there is more work to do and we haven't timed out */ while (keep_going && now <= expire_at) { keep_going = mongoc_topology_scanner_work (topology->scanner, (expire_at - now) / 1000); if (keep_going) { now = bson_get_monotonic_time (); } } return keep_going; } /* *-------------------------------------------------------------------------- * * _mongoc_topology_do_blocking_scan -- * * Monitoring entry for single-threaded use case. Assumes the caller * has checked that it's the right time to scan. * *-------------------------------------------------------------------------- */ static void _mongoc_topology_do_blocking_scan (mongoc_topology_t *topology, bson_error_t *error) { mongoc_topology_scanner_start (topology->scanner, topology->connect_timeout_msec, true); while (_mongoc_topology_run_scanner (topology, topology->connect_timeout_msec)) {} /* Aggregate all scanner errors, if any */ mongoc_topology_scanner_sum_errors (topology->scanner, error); /* "retired" nodes can be checked again in the next scan */ mongoc_topology_scanner_reset (topology->scanner); topology->last_scan = bson_get_monotonic_time (); topology->stale = false; } /* *------------------------------------------------------------------------- * * mongoc_topology_select -- * * Selects a server description for an operation based on @optype * and @read_prefs. * * NOTE: this method returns a copy of the original server * description. Callers must own and clean up this copy. * * NOTE: this method locks and unlocks @topology's mutex. * * Parameters: * @topology: The topology. * @optype: Whether we are selecting for a read or write operation. * @read_prefs: Required, the read preferences for the command. * @local_threshold_ms: Maximum latency *beyond* the nearest server * among which to randomly select servers. See Server Selection * Spec. * @error: Required, out pointer for error info. * * Returns: * A mongoc_server_description_t, or NULL on failure, in which case * @error will be set. * * Side effects: * @error may be set. * *------------------------------------------------------------------------- */ mongoc_server_description_t * mongoc_topology_select (mongoc_topology_t *topology, mongoc_ss_optype_t optype, const mongoc_read_prefs_t *read_prefs, int64_t local_threshold_ms, bson_error_t *error) { int r; mongoc_server_description_t *selected_server = NULL; bool try_once; int64_t sleep_usec; bool tried_once; bson_error_t scanner_error = { 0 }; /* These names come from the Server Selection Spec pseudocode */ int64_t loop_start; /* when we entered this function */ int64_t loop_end; /* when we last completed a loop (single-threaded) */ int64_t scan_ready; /* the soonest we can do a blocking scan */ int64_t next_update; /* the latest we must do a blocking scan */ int64_t expire_at; /* when server selection timeout expires */ BSON_ASSERT (topology); try_once = topology->server_selection_try_once; loop_start = loop_end = bson_get_monotonic_time (); expire_at = loop_start + ((int64_t) topology->server_selection_timeout_msec * 1000); if (topology->single_threaded) { tried_once = false; next_update = topology->last_scan + topology->heartbeat_msec * 1000; if (next_update < loop_start) { /* we must scan now */ topology->stale = true; } /* until we find a server or time out */ for (;;) { if (topology->stale) { /* how soon are we allowed to scan? */ scan_ready = topology->last_scan + MONGOC_TOPOLOGY_MIN_HEARTBEAT_FREQUENCY_MS * 1000; if (scan_ready > expire_at && !try_once) { /* selection timeout will expire before min heartbeat passes */ bson_set_error(error, MONGOC_ERROR_SERVER_SELECTION, MONGOC_ERROR_SERVER_SELECTION_FAILURE, "No suitable servers found: " "`minheartbeatfrequencyms` not reached yet"); goto FAIL; } sleep_usec = scan_ready - loop_end; if (sleep_usec > 0) { _mongoc_usleep (sleep_usec); } /* takes up to connectTimeoutMS. sets "last_scan", clears "stale" */ _mongoc_topology_do_blocking_scan (topology, &scanner_error); tried_once = true; } selected_server = mongoc_topology_description_select(&topology->description, optype, read_prefs, local_threshold_ms); if (selected_server) { return mongoc_server_description_new_copy(selected_server); } topology->stale = true; if (try_once) { if (tried_once) { if (scanner_error.code) { bson_set_error(error, MONGOC_ERROR_SERVER_SELECTION, MONGOC_ERROR_SERVER_SELECTION_FAILURE, "No suitable servers found " "(`serverselectiontryonce` set): %s", scanner_error.message); } else { bson_set_error(error, MONGOC_ERROR_SERVER_SELECTION, MONGOC_ERROR_SERVER_SELECTION_FAILURE, "No suitable servers found " "(`serverselectiontryonce` set)"); } goto FAIL; } } else { loop_end = bson_get_monotonic_time (); if (loop_end > expire_at) { /* no time left in server_selection_timeout_msec */ bson_set_error(error, MONGOC_ERROR_SERVER_SELECTION, MONGOC_ERROR_SERVER_SELECTION_FAILURE, "No suitable servers found: " "`serverselectiontimeoutms` timed out"); goto FAIL; } } } } /* With background thread */ /* we break out when we've found a server or timed out */ for (;;) { mongoc_mutex_lock (&topology->mutex); selected_server = mongoc_topology_description_select(&topology->description, optype, read_prefs, local_threshold_ms); if (! selected_server) { _mongoc_topology_request_scan (topology); r = mongoc_cond_timedwait (&topology->cond_client, &topology->mutex, (expire_at - loop_start) / 1000); mongoc_mutex_unlock (&topology->mutex); #ifdef _WIN32 if (r == WSAETIMEDOUT) { #else if (r == ETIMEDOUT) { #endif /* handle timeouts */ bson_set_error(error, MONGOC_ERROR_SERVER_SELECTION, MONGOC_ERROR_SERVER_SELECTION_FAILURE, "Timed out trying to select a server"); goto FAIL; } else if (r) { bson_set_error(error, MONGOC_ERROR_SERVER_SELECTION, MONGOC_ERROR_SERVER_SELECTION_FAILURE, "Unknown error '%d' received while waiting on thread condition", r); goto FAIL; } loop_start = bson_get_monotonic_time (); if (loop_start > expire_at) { bson_set_error(error, MONGOC_ERROR_SERVER_SELECTION, MONGOC_ERROR_SERVER_SELECTION_FAILURE, "Timed out trying to select a server"); goto FAIL; } } else { selected_server = mongoc_server_description_new_copy(selected_server); mongoc_mutex_unlock (&topology->mutex); return selected_server; } } FAIL: topology->stale = true; return NULL; } /* *------------------------------------------------------------------------- * * mongoc_topology_server_by_id -- * * Get the server description for @id, if that server is present * in @description. Otherwise, return NULL and fill out the optional * @error. * * NOTE: this method returns a copy of the original server * description. Callers must own and clean up this copy. * * NOTE: this method locks and unlocks @topology's mutex. * * Returns: * A mongoc_server_description_t, or NULL. * * Side effects: * Fills out optional @error if server not found. * *------------------------------------------------------------------------- */ mongoc_server_description_t * mongoc_topology_server_by_id (mongoc_topology_t *topology, uint32_t id, bson_error_t *error) { mongoc_server_description_t *sd; mongoc_mutex_lock (&topology->mutex); sd = mongoc_server_description_new_copy ( mongoc_topology_description_server_by_id (&topology->description, id, error)); mongoc_mutex_unlock (&topology->mutex); return sd; } /* *------------------------------------------------------------------------- * * mongoc_topology_get_server_type -- * * Get the topology type, and the server type for @id, if that server * is present in @description. Otherwise, return false and fill out * the optional @error. * * NOTE: this method locks and unlocks @topology's mutex. * * Returns: * True on success. * * Side effects: * Fills out optional @error if server not found. * *------------------------------------------------------------------------- */ bool mongoc_topology_get_server_type ( mongoc_topology_t *topology, uint32_t id, mongoc_topology_description_type_t *topology_type /* OUT */, mongoc_server_description_type_t *server_type /* OUT */, bson_error_t *error) { mongoc_server_description_t *sd; bool ret = false; BSON_ASSERT (topology); BSON_ASSERT (topology_type); BSON_ASSERT (server_type); mongoc_mutex_lock (&topology->mutex); sd = mongoc_topology_description_server_by_id (&topology->description, id, error); if (sd) { *topology_type = topology->description.type; *server_type = sd->type; ret = true; } mongoc_mutex_unlock (&topology->mutex); return ret; } /* *-------------------------------------------------------------------------- * * _mongoc_topology_request_scan -- * * Non-locking variant * *-------------------------------------------------------------------------- */ static void _mongoc_topology_request_scan (mongoc_topology_t *topology) { topology->scan_requested = true; mongoc_cond_signal (&topology->cond_server); } /* *-------------------------------------------------------------------------- * * mongoc_topology_request_scan -- * * Used from within the driver to request an immediate topology check. * * NOTE: this method locks and unlocks @topology's mutex. * *-------------------------------------------------------------------------- */ void mongoc_topology_request_scan (mongoc_topology_t *topology) { mongoc_mutex_lock (&topology->mutex); _mongoc_topology_request_scan (topology); mongoc_mutex_unlock (&topology->mutex); } /* *-------------------------------------------------------------------------- * * mongoc_topology_invalidate_server -- * * Invalidate the given server after receiving a network error in * another part of the client. * * NOTE: this method uses @topology's mutex. * *-------------------------------------------------------------------------- */ void mongoc_topology_invalidate_server (mongoc_topology_t *topology, uint32_t id) { mongoc_mutex_lock (&topology->mutex); mongoc_topology_description_invalidate_server (&topology->description, id); mongoc_mutex_unlock (&topology->mutex); } /* *-------------------------------------------------------------------------- * * mongoc_topology_server_timestamp -- * * Return the topology's scanner's timestamp for the given server, * or -1 if there is no scanner node for the given server. * * NOTE: this method uses @topology's mutex. * * Returns: * Timestamp, or -1 * *-------------------------------------------------------------------------- */ int64_t mongoc_topology_server_timestamp (mongoc_topology_t *topology, uint32_t id) { mongoc_topology_scanner_node_t *node; int64_t timestamp = -1; mongoc_mutex_lock (&topology->mutex); node = mongoc_topology_scanner_get_node (topology->scanner, id); if (node) { timestamp = node->timestamp; } mongoc_mutex_unlock (&topology->mutex); return timestamp; } /* *-------------------------------------------------------------------------- * * _mongoc_topology_run_background -- * * The background topology monitoring thread runs in this loop. * * NOTE: this method uses @topology's mutex. * *-------------------------------------------------------------------------- */ static void * _mongoc_topology_run_background (void *data) { mongoc_topology_t *topology; int64_t now; int64_t last_scan; int64_t timeout; int64_t force_timeout; int r; BSON_ASSERT (data); last_scan = 0; topology = (mongoc_topology_t *)data; /* we exit this loop when shutdown_requested, or on error */ for (;;) { /* unlocked after starting a scan or after breaking out of the loop */ mongoc_mutex_lock (&topology->mutex); /* we exit this loop on error, or when we should scan immediately */ for (;;) { if (topology->shutdown_requested) goto DONE; now = bson_get_monotonic_time (); if (last_scan == 0) { /* set up the "last scan" as exactly long enough to force an * immediate scan on the first pass */ last_scan = now - (topology->heartbeat_msec * 1000); } timeout = topology->heartbeat_msec - ((now - last_scan) / 1000); /* if someone's specifically asked for a scan, use a shorter interval */ if (topology->scan_requested) { force_timeout = MONGOC_TOPOLOGY_MIN_HEARTBEAT_FREQUENCY_MS - ((now - last_scan) / 1000); timeout = BSON_MIN (timeout, force_timeout); } /* if we can start scanning, do so immediately */ if (timeout <= 0) { mongoc_topology_scanner_start (topology->scanner, topology->connect_timeout_msec, false); break; } else { /* otherwise wait until someone: * o requests a scan * o we time out * o requests a shutdown */ r = mongoc_cond_timedwait (&topology->cond_server, &topology->mutex, timeout); #ifdef _WIN32 if (! (r == 0 || r == WSAETIMEDOUT)) { #else if (! (r == 0 || r == ETIMEDOUT)) { #endif /* handle errors */ goto DONE; } /* if we timed out, or were woken up, check if it's time to scan * again, or bail out */ } } topology->scan_requested = false; topology->scanning = true; /* scanning locks and unlocks the mutex itself until the scan is done */ mongoc_mutex_unlock (&topology->mutex); while (_mongoc_topology_run_scanner (topology, topology->connect_timeout_msec)) {} mongoc_mutex_lock (&topology->mutex); /* "retired" nodes can be checked again in the next scan */ mongoc_topology_scanner_reset (topology->scanner); topology->last_scan = bson_get_monotonic_time (); topology->scanning = false; mongoc_mutex_unlock (&topology->mutex); last_scan = bson_get_monotonic_time(); } DONE: mongoc_mutex_unlock (&topology->mutex); return NULL; } /* *-------------------------------------------------------------------------- * * mongoc_topology_background_thread_start -- * * Start the topology background thread running. This should only be * called once per pool. If clients are created separately (not * through a pool) the SDAM logic will not be run in a background * thread. * * NOTE: this method uses @topology's mutex. * *-------------------------------------------------------------------------- */ static void _mongoc_topology_background_thread_start (mongoc_topology_t *topology) { bool launch_thread = true; if (topology->single_threaded) { return; } mongoc_mutex_lock (&topology->mutex); if (topology->bg_thread_state != MONGOC_TOPOLOGY_BG_OFF) launch_thread = false; topology->bg_thread_state = MONGOC_TOPOLOGY_BG_RUNNING; mongoc_mutex_unlock (&topology->mutex); if (launch_thread) { mongoc_thread_create (&topology->thread, _mongoc_topology_run_background, topology); } } /* *-------------------------------------------------------------------------- * * mongoc_topology_background_thread_stop -- * * Stop the topology background thread. Called by the owning pool at * its destruction. * * NOTE: this method uses @topology's mutex. * *-------------------------------------------------------------------------- */ static void _mongoc_topology_background_thread_stop (mongoc_topology_t *topology) { bool join_thread = false; if (topology->single_threaded) { return; } mongoc_mutex_lock (&topology->mutex); if (topology->bg_thread_state == MONGOC_TOPOLOGY_BG_RUNNING) { /* if the background thread is running, request a shutdown and signal the * thread */ topology->shutdown_requested = true; mongoc_cond_signal (&topology->cond_server); topology->bg_thread_state = MONGOC_TOPOLOGY_BG_SHUTTING_DOWN; join_thread = true; } else if (topology->bg_thread_state == MONGOC_TOPOLOGY_BG_SHUTTING_DOWN) { /* if we're mid shutdown, wait until it shuts down */ while (topology->bg_thread_state != MONGOC_TOPOLOGY_BG_OFF) { mongoc_cond_wait (&topology->cond_client, &topology->mutex); } } else { /* nothing to do if it's already off */ } mongoc_mutex_unlock (&topology->mutex); if (join_thread) { /* if we're joining the thread, wait for it to come back and broadcast * all listeners */ mongoc_thread_join (topology->thread); mongoc_cond_broadcast (&topology->cond_client); } } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-trace.h0000664000175000017500000000436612673034026022357 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_TRACE_PRIVATE_H #define MONGOC_TRACE_PRIVATE_H #include #include #include "mongoc-log.h" #include "mongoc-log-private.h" BSON_BEGIN_DECLS #ifdef MONGOC_TRACE #define TRACE(msg, ...) \ do { mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "TRACE: %s():%d " msg, BSON_FUNC, __LINE__, __VA_ARGS__); } while (0) #define ENTRY do { mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "ENTRY: %s():%d", BSON_FUNC, __LINE__); } while (0) #define EXIT do { mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, " EXIT: %s():%d", BSON_FUNC, __LINE__); return; } while (0) #define RETURN(ret) do { mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, " EXIT: %s():%d", BSON_FUNC, __LINE__); return ret; } while (0) #define GOTO(label) do { mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, " GOTO: %s():%d %s", BSON_FUNC, __LINE__, #label); goto label; } while (0) #define DUMP_BYTES(_n, _b, _l) do { \ mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "TRACE: %s():%d %s = %p [%d]", BSON_FUNC, __LINE__, #_n, _b, (int)_l); \ mongoc_log_trace_bytes(MONGOC_LOG_DOMAIN, _b, _l); \ } while (0) #define DUMP_IOVEC(_n, _iov, _iovcnt) do { \ mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "TRACE: %s():%d %s = %p [%d]", BSON_FUNC, __LINE__, #_n, _iov, (int)_iovcnt); \ mongoc_log_trace_iovec(MONGOC_LOG_DOMAIN, _iov, _iovcnt); \ } while (0) #else #define TRACE(msg,...) #define ENTRY #define EXIT return #define RETURN(ret) return ret #define GOTO(label) goto label #define DUMP_BYTES(_n, _b, _l) #define DUMP_IOVEC(_n, _iov, _iovcnt) #endif BSON_END_DECLS #endif /* MONGOC_TRACE_PRIVATE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-uri-private.h0000664000175000017500000000624712673034026023530 0ustar jmikolajmikola/* * Copyright 2015 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_URI_PRIVATE_H #define MONGOC_URI_PRIVATE_H #if !defined (MONGOC_I_AM_A_DRIVER) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #include "mongoc-uri.h" BSON_BEGIN_DECLS void mongoc_uri_lowercase_hostname ( const char *src, char *buf /* OUT */, int len); void mongoc_uri_append_host ( mongoc_uri_t *uri, const char *host, uint16_t port); bool mongoc_uri_parse_host ( mongoc_uri_t *uri, const char *str); bool mongoc_uri_set_username ( mongoc_uri_t *uri, const char *username); bool mongoc_uri_set_password ( mongoc_uri_t *uri, const char *password); bool mongoc_uri_set_database ( mongoc_uri_t *uri, const char *database); bool mongoc_uri_set_auth_source ( mongoc_uri_t *uri, const char *value); bool mongoc_uri_option_is_int32 (const char *key); bool mongoc_uri_option_is_bool (const char *key); bool mongoc_uri_option_is_utf8 (const char *key); int32_t mongoc_uri_get_option_as_int32 (const mongoc_uri_t *uri, const char *option, int32_t fallback); bool mongoc_uri_get_option_as_bool (const mongoc_uri_t *uri, const char *option, bool fallback); const char* mongoc_uri_get_option_as_utf8 (const mongoc_uri_t *uri, const char *option, const char *fallback); bool mongoc_uri_set_option_as_int32 ( mongoc_uri_t *uri, const char *option, int32_t value); bool mongoc_uri_set_option_as_bool ( mongoc_uri_t *uri, const char *option, bool value); bool mongoc_uri_set_option_as_utf8 ( mongoc_uri_t *uri, const char *option, const char *value); BSON_END_DECLS #endif /* MONGOC_URI_PRIVATE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-uri.c0000664000175000017500000011424012673034026022044 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include /* strcasecmp on windows */ #include "mongoc-util-private.h" #include "mongoc-host-list.h" #include "mongoc-host-list-private.h" #include "mongoc-log.h" #include "mongoc-socket.h" #include "mongoc-uri-private.h" #include "mongoc-read-concern-private.h" #include "mongoc-write-concern-private.h" struct _mongoc_uri_t { char *str; mongoc_host_list_t *hosts; char *username; char *password; char *database; bson_t options; bson_t credentials; mongoc_read_prefs_t *read_prefs; mongoc_read_concern_t *read_concern; mongoc_write_concern_t *write_concern; }; static void mongoc_uri_do_unescape (char **str) { char *tmp; if ((tmp = *str)) { *str = mongoc_uri_unescape(tmp); bson_free(tmp); } } void mongoc_uri_lowercase_hostname (const char *src, char *buf /* OUT */, int len) { bson_unichar_t c; const char *iter; char *buf_iter; /* TODO: this code only accepts ascii, and assumes that lowercased chars are the same width as originals */ for (iter = src, buf_iter = buf; iter && *iter && (c = bson_utf8_get_char(iter)) && buf_iter - buf < len; iter = bson_utf8_next_char(iter), buf_iter++) { assert(c < 128); *buf_iter = tolower(c); } } void mongoc_uri_append_host (mongoc_uri_t *uri, const char *host, uint16_t port) { mongoc_host_list_t *iter; mongoc_host_list_t *link_; link_ = (mongoc_host_list_t *)bson_malloc0(sizeof *link_); mongoc_uri_lowercase_hostname(host, link_->host, sizeof link_->host); if (strchr (host, ':')) { bson_snprintf (link_->host_and_port, sizeof link_->host_and_port, "[%s]:%hu", host, port); link_->family = AF_INET6; } else { bson_snprintf (link_->host_and_port, sizeof link_->host_and_port, "%s:%hu", host, port); link_->family = strstr (host, ".sock") ? AF_UNIX : AF_INET; } link_->host_and_port[sizeof link_->host_and_port - 1] = '\0'; link_->port = port; if ((iter = uri->hosts)) { for (; iter && iter->next; iter = iter->next) {} iter->next = link_; } else { uri->hosts = link_; } } /* *-------------------------------------------------------------------------- * * scan_to_unichar -- * * Scans 'str' until either a character matching 'match' is found, * until one of the characters in 'terminators' is encountered, or * until we reach the end of 'str'. * * NOTE: 'terminators' may not include multibyte UTF-8 characters. * * Returns: * If 'match' is found, returns a copy of the section of 'str' before * that character. Otherwise, returns NULL. * * Side Effects: * If 'match' is found, sets 'end' to begin at the matching character * in 'str'. * *-------------------------------------------------------------------------- */ static char * scan_to_unichar (const char *str, bson_unichar_t match, const char *terminators, const char **end) { bson_unichar_t c; const char *iter; for (iter = str; iter && *iter && (c = bson_utf8_get_char(iter)); iter = bson_utf8_next_char(iter)) { if (c == match) { *end = iter; return bson_strndup(str, iter - str); } else if (c == '\\') { iter = bson_utf8_next_char(iter); if (!bson_utf8_get_char(iter)) { break; } } else { const char *term_iter; for (term_iter = terminators; *term_iter; term_iter++) { if (c == *term_iter) { return NULL; } } } } return NULL; } static bool mongoc_uri_parse_scheme (const char *str, const char **end) { if (!!strncmp(str, "mongodb://", 10)) { return false; } *end = str + 10; return true; } static bool mongoc_uri_parse_userpass (mongoc_uri_t *uri, const char *str, const char **end) { bool ret = false; const char *end_userpass; const char *end_user; char *s; if ((s = scan_to_unichar(str, '@', "", &end_userpass))) { if ((uri->username = scan_to_unichar(s, ':', "", &end_user))) { uri->password = bson_strdup(end_user + 1); } else { uri->username = bson_strndup(str, end_userpass - str); uri->password = NULL; } mongoc_uri_do_unescape(&uri->username); mongoc_uri_do_unescape(&uri->password); *end = end_userpass + 1; bson_free(s); ret = true; } else { ret = true; } return ret; } static bool mongoc_uri_parse_port (uint16_t *port, const char *str) { unsigned long ul_port; ul_port = strtoul (str, NULL, 10); if (ul_port == 0 || ul_port > UINT16_MAX) { /* Parse error or port number out of range. mongod prohibits port 0. */ return false; } *port = (uint16_t)ul_port; return true; } static bool mongoc_uri_parse_host6 (mongoc_uri_t *uri, const char *str) { uint16_t port = MONGOC_DEFAULT_PORT; const char *portstr; const char *end_host; char *hostname; if ((portstr = strrchr (str, ':')) && !strstr (portstr, "]")) { if (!mongoc_uri_parse_port(&port, portstr + 1)) { return false; } } hostname = scan_to_unichar (str + 1, ']', "", &end_host); mongoc_uri_do_unescape (&hostname); if (!hostname) { return false; } mongoc_uri_append_host (uri, hostname, port); bson_free (hostname); return true; } bool mongoc_uri_parse_host (mongoc_uri_t *uri, const char *str) { uint16_t port; const char *end_host; char *hostname; if (*str == '[' && strchr (str, ']')) { return mongoc_uri_parse_host6 (uri, str); } if ((hostname = scan_to_unichar(str, ':', "?/,", &end_host))) { end_host++; if (!mongoc_uri_parse_port(&port, end_host)) { bson_free (hostname); return false; } } else { hostname = bson_strdup(str); port = MONGOC_DEFAULT_PORT; } mongoc_uri_do_unescape(&hostname); if (!hostname) { /* invalid */ bson_free (hostname); return false; } mongoc_uri_append_host(uri, hostname, port); bson_free(hostname); return true; } bool _mongoc_host_list_from_string (mongoc_host_list_t *host_list, const char *host_and_port) { bool rval = false; char *uri_str = NULL; mongoc_uri_t *uri = NULL; const mongoc_host_list_t *uri_hl; BSON_ASSERT (host_list); BSON_ASSERT (host_and_port); uri_str = bson_strdup_printf("mongodb://%s/", host_and_port); if (! uri_str) goto CLEANUP; uri = mongoc_uri_new(uri_str); if (! uri) goto CLEANUP; uri_hl = mongoc_uri_get_hosts(uri); if (uri_hl->next) goto CLEANUP; memcpy(host_list, uri_hl, sizeof(*uri_hl)); rval = true; CLEANUP: bson_free(uri_str); if (uri) mongoc_uri_destroy(uri); return rval; } static bool mongoc_uri_parse_hosts (mongoc_uri_t *uri, const char *str, const char **end) { bool ret = false; const char *end_hostport; const char *sock; const char *tmp; char *s; /* * Parsing the series of hosts is a lot more complicated than you might * imagine. This is due to some characters being both separators as well as * valid characters within the "hostname". In particularly, we can have file * paths to specify paths to UNIX domain sockets. We impose the restriction * that they must be suffixed with ".sock" to simplify the parsing. * * You can separate hosts and file system paths to UNIX domain sockets with * ",". * * When you reach a "/" or "?" that is not part of a file-system path, we * have completed our parsing of hosts. */ again: if (((*str == '/') && (sock = strstr(str, ".sock"))) && (!(tmp = strstr(str, ",")) || (tmp > sock)) && (!(tmp = strstr(str, "?")) || (tmp > sock))) { s = bson_strndup(str, sock + 5 - str); if (!mongoc_uri_parse_host(uri, s)) { bson_free(s); return false; } bson_free(s); str = sock + 5; ret = true; if (*str == ',') { str++; goto again; } } else if ((s = scan_to_unichar(str, ',', "/", &end_hostport))) { if (!mongoc_uri_parse_host(uri, s)) { bson_free(s); return false; } bson_free(s); str = end_hostport + 1; ret = true; goto again; } else if ((s = scan_to_unichar(str, '/', "", &end_hostport)) || (s = scan_to_unichar(str, '?', "", &end_hostport))) { if (!mongoc_uri_parse_host(uri, s)) { bson_free(s); return false; } bson_free(s); *end = end_hostport; return true; } else if (*str) { if (!mongoc_uri_parse_host(uri, str)) { return false; } *end = str + strlen(str); return true; } return ret; } static bool mongoc_uri_parse_database (mongoc_uri_t *uri, const char *str, const char **end) { const char *end_database; if ((uri->database = scan_to_unichar(str, '?', "", &end_database))) { *end = end_database; } else if (*str) { uri->database = bson_strdup(str); *end = str + strlen(str); } mongoc_uri_do_unescape(&uri->database); if (!uri->database) { /* invalid */ return false; } return true; } static bool mongoc_uri_parse_auth_mechanism_properties (mongoc_uri_t *uri, const char *str) { char *field; char *value; const char *end_scan; bson_t properties; bson_init(&properties); /* build up the properties document */ while ((field = scan_to_unichar(str, ':', "&", &end_scan))) { str = end_scan + 1; if (!(value = scan_to_unichar(str, ',', ":&", &end_scan))) { value = bson_strdup(str); str = ""; } else { str = end_scan + 1; } bson_append_utf8(&properties, field, -1, value, -1); bson_free(field); bson_free(value); } /* append our auth properties to our credentials */ bson_append_document(&uri->credentials, "mechanismProperties", -1, (const bson_t *)&properties); return true; } static void mongoc_uri_parse_tags (mongoc_uri_t *uri, /* IN */ const char *str) /* IN */ { const char *end_keyval; const char *end_key; bson_t b; char *keyval; char *key; bson_init(&b); again: if ((keyval = scan_to_unichar(str, ',', "", &end_keyval))) { if ((key = scan_to_unichar(keyval, ':', "", &end_key))) { bson_append_utf8(&b, key, -1, end_key + 1, -1); bson_free(key); } bson_free(keyval); str = end_keyval + 1; goto again; } else { if ((key = scan_to_unichar(str, ':', "", &end_key))) { bson_append_utf8(&b, key, -1, end_key + 1, -1); bson_free(key); } } mongoc_read_prefs_add_tag(uri->read_prefs, &b); bson_destroy(&b); } /* *-------------------------------------------------------------------------- * * mongoc_uri_bson_append_or_replace_key -- * * * Appends 'option' to the end of 'options' if not already set. * * Since we cannot grow utf8 strings inline, we have to allocate a temporary * bson variable and splice in the new value if the key is already set. * * NOTE: This function keeps the order of the BSON keys. * * NOTE: 'option' is case*in*sensitive. * * *-------------------------------------------------------------------------- */ static void mongoc_uri_bson_append_or_replace_key (bson_t *options, const char *option, const char *value) { bson_iter_t iter; bool found = false; if (bson_iter_init (&iter, options)) { bson_t tmp = BSON_INITIALIZER; while (bson_iter_next (&iter)) { const bson_value_t *bvalue; if (!strcasecmp(bson_iter_key (&iter), option)) { bson_append_utf8(&tmp, option, -1, value, -1); found = true; continue; } bvalue = bson_iter_value (&iter); BSON_APPEND_VALUE (&tmp, bson_iter_key (&iter), bvalue); } if (! found) { bson_append_utf8(&tmp, option, -1, value, -1); } bson_destroy (options); bson_copy_to (&tmp, options); bson_destroy (&tmp); } } bool mongoc_uri_option_is_int32 (const char *key) { return !strcasecmp(key, "connecttimeoutms") || !strcasecmp(key, "heartbeatfrequencyms") || !strcasecmp(key, "serverselectiontimeoutms") || !strcasecmp(key, "socketcheckintervalms") || !strcasecmp(key, "sockettimeoutms") || !strcasecmp(key, "maxpoolsize") || !strcasecmp(key, "minpoolsize") || !strcasecmp(key, "maxidletimems") || !strcasecmp(key, "waitqueuemultiple") || !strcasecmp(key, "waitqueuetimeoutms") || !strcasecmp(key, "wtimeoutms"); } bool mongoc_uri_option_is_bool (const char *key) { return !strcasecmp(key, "canonicalizeHostname") || !strcasecmp(key, "journal") || !strcasecmp(key, "safe") || !strcasecmp(key, "serverSelectionTryOnce") || !strcasecmp(key, "slaveok") || !strcasecmp(key, "ssl"); } bool mongoc_uri_option_is_utf8 (const char *key) { if (mongoc_uri_option_is_bool(key) || mongoc_uri_option_is_int32(key)) { return false; } if (!strcasecmp(key, "readpreferencetags") || !strcasecmp(key, "authmechanismproperties")) { return false; } if (!strcasecmp(key, "username") || !strcasecmp(key, "password") || !strcasecmp(key, "authsource") || !strcasecmp(key, "database")) { return false; } return true; } static bool mongoc_uri_parse_option (mongoc_uri_t *uri, const char *str) { int32_t v_int; const char *end_key; char *key = NULL; char *value = NULL; bool ret = false; if (!(key = scan_to_unichar(str, '=', "", &end_key))) { goto CLEANUP; } value = bson_strdup(end_key + 1); mongoc_uri_do_unescape(&value); if (!value) { /* do_unescape detected invalid UTF-8 and freed value */ goto CLEANUP; } if (mongoc_uri_option_is_int32(key)) { v_int = (int) strtol (value, NULL, 10); BSON_APPEND_INT32 (&uri->options, key, v_int); } else if (!strcasecmp(key, "w")) { if (*value == '-' || isdigit(*value)) { v_int = (int) strtol (value, NULL, 10); BSON_APPEND_INT32 (&uri->options, "w", v_int); } else if (0 == strcasecmp (value, "majority")) { BSON_APPEND_UTF8 (&uri->options, "w", "majority"); } else if (*value) { BSON_APPEND_UTF8 (&uri->options, "w", value); } } else if (mongoc_uri_option_is_bool(key)) { bson_append_bool (&uri->options, key, -1, (0 == strcasecmp (value, "true")) || (0 == strcasecmp (value, "t")) || (0 == strcmp (value, "1"))); } else if (!strcasecmp(key, "readpreferencetags")) { mongoc_uri_parse_tags(uri, value); } else if (!strcasecmp(key, "authmechanism") || !strcasecmp(key, "authsource")) { bson_append_utf8(&uri->credentials, key, -1, value, -1); } else if (!strcasecmp(key, "readconcernlevel")) { mongoc_read_concern_set_level (uri->read_concern, value); } else if (!strcasecmp(key, "authmechanismproperties")) { if (!mongoc_uri_parse_auth_mechanism_properties(uri, value)) { bson_free(key); bson_free(value); return false; } } else { bson_append_utf8(&uri->options, key, -1, value, -1); } ret = true; CLEANUP: bson_free(key); bson_free(value); return ret; } static bool mongoc_uri_parse_options (mongoc_uri_t *uri, const char *str) { const char *end_option; char *option; again: if ((option = scan_to_unichar(str, '&', "", &end_option))) { if (!mongoc_uri_parse_option(uri, option)) { bson_free(option); return false; } bson_free(option); str = end_option + 1; goto again; } else if (*str) { if (!mongoc_uri_parse_option(uri, str)) { return false; } } return true; } static bool mongoc_uri_finalize_auth (mongoc_uri_t *uri) { bson_iter_t iter; const char *source = NULL; const char *mechanism = mongoc_uri_get_auth_mechanism(uri); if (bson_iter_init_find_case(&iter, &uri->credentials, "authSource")) { source = bson_iter_utf8(&iter, NULL); } /* authSource with GSSAPI or X509 should always be external */ if (mechanism) { if (!strcasecmp(mechanism, "GSSAPI") || !strcasecmp(mechanism, "MONGODB-X509")) { if (source) { if (strcasecmp(source, "$external")) { return false; } } else { bson_append_utf8(&uri->credentials, "authsource", -1, "$external", -1); } } } return true; } static bool mongoc_uri_parse (mongoc_uri_t *uri, const char *str) { if (!mongoc_uri_parse_scheme(str, &str)) { return false; } if (!*str || !mongoc_uri_parse_userpass(uri, str, &str)) { return false; } if (!*str || !mongoc_uri_parse_hosts(uri, str, &str)) { return false; } switch (*str) { case '/': str++; if (*str && !mongoc_uri_parse_database(uri, str, &str)) { return false; } if (!*str) { break; } /* Fall through */ case '?': str++; if (*str && !mongoc_uri_parse_options(uri, str)) { return false; } break; default: break; } return mongoc_uri_finalize_auth(uri); } const mongoc_host_list_t * mongoc_uri_get_hosts (const mongoc_uri_t *uri) { BSON_ASSERT (uri); return uri->hosts; } const char * mongoc_uri_get_replica_set (const mongoc_uri_t *uri) { bson_iter_t iter; BSON_ASSERT (uri); if (bson_iter_init_find_case(&iter, &uri->options, "replicaSet") && BSON_ITER_HOLDS_UTF8(&iter)) { return bson_iter_utf8(&iter, NULL); } return NULL; } const bson_t * mongoc_uri_get_credentials (const mongoc_uri_t *uri) { BSON_ASSERT (uri); return &uri->credentials; } const char * mongoc_uri_get_auth_mechanism (const mongoc_uri_t *uri) { bson_iter_t iter; BSON_ASSERT (uri); if (bson_iter_init_find_case (&iter, &uri->credentials, "authMechanism") && BSON_ITER_HOLDS_UTF8 (&iter)) { return bson_iter_utf8 (&iter, NULL); } return NULL; } bool mongoc_uri_get_mechanism_properties (const mongoc_uri_t *uri, bson_t *properties) { bson_iter_t iter; if (!uri) { return false; } if (bson_iter_init_find_case (&iter, &uri->credentials, "mechanismProperties") && BSON_ITER_HOLDS_DOCUMENT (&iter)) { uint32_t len = 0; const uint8_t *data = NULL; bson_iter_document (&iter, &len, &data); bson_init_static (properties, data, len); return true; } return false; } static void _mongoc_uri_assign_read_prefs_mode (mongoc_uri_t *uri) /* IN */ { const char *str; bson_iter_t iter; BSON_ASSERT(uri); if (mongoc_uri_get_option_as_bool (uri, "slaveok", false)) { mongoc_read_prefs_set_mode(uri->read_prefs, MONGOC_READ_SECONDARY_PREFERRED); } if (bson_iter_init_find_case(&iter, &uri->options, "readpreference") && BSON_ITER_HOLDS_UTF8(&iter)) { str = bson_iter_utf8(&iter, NULL); if (0 == strcasecmp("primary", str)) { mongoc_read_prefs_set_mode(uri->read_prefs, MONGOC_READ_PRIMARY); } else if (0 == strcasecmp("primarypreferred", str)) { mongoc_read_prefs_set_mode(uri->read_prefs, MONGOC_READ_PRIMARY_PREFERRED); } else if (0 == strcasecmp("secondary", str)) { mongoc_read_prefs_set_mode(uri->read_prefs, MONGOC_READ_SECONDARY); } else if (0 == strcasecmp("secondarypreferred", str)) { mongoc_read_prefs_set_mode(uri->read_prefs, MONGOC_READ_SECONDARY_PREFERRED); } else if (0 == strcasecmp("nearest", str)) { mongoc_read_prefs_set_mode(uri->read_prefs, MONGOC_READ_NEAREST); } else { MONGOC_WARNING("Unsupported readPreference value [readPreference=%s].", str); } } /* Warn on conflict, since read preference will be validated later */ if (mongoc_read_prefs_get_mode(uri->read_prefs) == MONGOC_READ_PRIMARY && !bson_empty(mongoc_read_prefs_get_tags(uri->read_prefs))) { MONGOC_WARNING("Primary read preference mode conflicts with tags."); } } static void _mongoc_uri_build_write_concern (mongoc_uri_t *uri) /* IN */ { mongoc_write_concern_t *write_concern; const char *str; bson_iter_t iter; int32_t wtimeoutms; int value; BSON_ASSERT (uri); write_concern = mongoc_write_concern_new (); if (bson_iter_init_find_case (&iter, &uri->options, "safe") && BSON_ITER_HOLDS_BOOL (&iter)) { mongoc_write_concern_set_w (write_concern, bson_iter_bool (&iter) ? 1 : MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED); } wtimeoutms = mongoc_uri_get_option_as_int32(uri, "wtimeoutms", 0); if (bson_iter_init_find_case (&iter, &uri->options, "journal") && BSON_ITER_HOLDS_BOOL (&iter)) { mongoc_write_concern_set_journal (write_concern, bson_iter_bool (&iter)); } if (bson_iter_init_find_case (&iter, &uri->options, "w")) { if (BSON_ITER_HOLDS_INT32 (&iter)) { value = bson_iter_int32 (&iter); switch (value) { case MONGOC_WRITE_CONCERN_W_ERRORS_IGNORED: case MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED: /* Warn on conflict, since write concern will be validated later */ if (mongoc_write_concern_get_journal(write_concern)) { MONGOC_WARNING("Journal conflicts with w value [w=%d].", value); } mongoc_write_concern_set_w(write_concern, value); break; default: if (value > 0) { mongoc_write_concern_set_w (write_concern, value); if (value > 1) { mongoc_write_concern_set_wtimeout (write_concern, wtimeoutms); } break; } MONGOC_WARNING ("Unsupported w value [w=%d].", value); break; } } else if (BSON_ITER_HOLDS_UTF8 (&iter)) { str = bson_iter_utf8 (&iter, NULL); if (0 == strcasecmp ("majority", str)) { mongoc_write_concern_set_wmajority (write_concern, wtimeoutms); } else { mongoc_write_concern_set_wtag (write_concern, str); mongoc_write_concern_set_wtimeout (write_concern, wtimeoutms); } } else { BSON_ASSERT (false); } } uri->write_concern = write_concern; } mongoc_uri_t * mongoc_uri_new (const char *uri_string) { mongoc_uri_t *uri; uri = (mongoc_uri_t *)bson_malloc0(sizeof *uri); bson_init(&uri->options); bson_init(&uri->credentials); /* Initialize read_prefs since tag parsing may add to it */ uri->read_prefs = mongoc_read_prefs_new(MONGOC_READ_PRIMARY); /* Initialize empty read_concern */ uri->read_concern = mongoc_read_concern_new (); if (!uri_string) { uri_string = "mongodb://127.0.0.1/"; } if (!mongoc_uri_parse(uri, uri_string)) { mongoc_uri_destroy(uri); return NULL; } uri->str = bson_strdup(uri_string); _mongoc_uri_assign_read_prefs_mode(uri); if (!mongoc_read_prefs_is_valid(uri->read_prefs)) { mongoc_uri_destroy(uri); return NULL; } _mongoc_uri_build_write_concern (uri); if (!_mongoc_write_concern_is_valid(uri->write_concern)) { mongoc_uri_destroy(uri); return NULL; } return uri; } mongoc_uri_t * mongoc_uri_new_for_host_port (const char *hostname, uint16_t port) { mongoc_uri_t *uri; char *str; BSON_ASSERT (hostname); BSON_ASSERT (port); str = bson_strdup_printf("mongodb://%s:%hu/", hostname, port); uri = mongoc_uri_new(str); bson_free(str); return uri; } const char * mongoc_uri_get_username (const mongoc_uri_t *uri) { BSON_ASSERT (uri); return uri->username; } bool mongoc_uri_set_username (mongoc_uri_t *uri, const char *username) { size_t len; BSON_ASSERT (username); len = strlen(username); if (!bson_utf8_validate (username, len, false)) { return false; } if (uri->username) { bson_free (uri->username); } uri->username = bson_strdup (username); return true; } const char * mongoc_uri_get_password (const mongoc_uri_t *uri) { BSON_ASSERT (uri); return uri->password; } bool mongoc_uri_set_password (mongoc_uri_t *uri, const char *password) { size_t len; BSON_ASSERT (password); len = strlen(password); if (!bson_utf8_validate (password, len, false)) { return false; } if (uri->password) { bson_free (uri->password); } uri->password = bson_strdup (password); return true; } const char * mongoc_uri_get_database (const mongoc_uri_t *uri) { BSON_ASSERT (uri); return uri->database; } bool mongoc_uri_set_database (mongoc_uri_t *uri, const char *database) { size_t len; BSON_ASSERT (database); len = strlen(database); if (!bson_utf8_validate (database, len, false)) { return false; } if (uri->database) { bson_free (uri->database); } uri->database = bson_strdup(database); return true; } const char * mongoc_uri_get_auth_source (const mongoc_uri_t *uri) { bson_iter_t iter; BSON_ASSERT (uri); if (bson_iter_init_find_case(&iter, &uri->credentials, "authSource")) { return bson_iter_utf8(&iter, NULL); } return uri->database ? uri->database : "admin"; } bool mongoc_uri_set_auth_source (mongoc_uri_t *uri, const char *value) { size_t len; BSON_ASSERT (value); len = strlen(value); if (!bson_utf8_validate (value, len, false)) { return false; } mongoc_uri_bson_append_or_replace_key (&uri->credentials, "authSource", value); return true; } const bson_t * mongoc_uri_get_options (const mongoc_uri_t *uri) { BSON_ASSERT (uri); return &uri->options; } void mongoc_uri_destroy (mongoc_uri_t *uri) { if (uri) { _mongoc_host_list_destroy_all (uri->hosts); bson_free(uri->str); bson_free(uri->database); bson_free(uri->username); bson_destroy(&uri->options); bson_destroy(&uri->credentials); mongoc_read_prefs_destroy(uri->read_prefs); mongoc_read_concern_destroy(uri->read_concern); mongoc_write_concern_destroy(uri->write_concern); if (uri->password) { bson_zero_free(uri->password, strlen(uri->password)); } bson_free(uri); } } mongoc_uri_t * mongoc_uri_copy (const mongoc_uri_t *uri) { mongoc_uri_t *copy; mongoc_host_list_t *iter; BSON_ASSERT (uri); copy = (mongoc_uri_t *)bson_malloc0(sizeof (*copy)); copy->str = bson_strdup (uri->str); copy->username = bson_strdup (uri->username); copy->password = bson_strdup (uri->password); copy->database = bson_strdup (uri->database); copy->read_prefs = mongoc_read_prefs_copy (uri->read_prefs); copy->read_concern = mongoc_read_concern_copy (uri->read_concern); copy->write_concern = mongoc_write_concern_copy (uri->write_concern); for (iter = uri->hosts; iter; iter = iter->next) { mongoc_uri_append_host (copy, iter->host, iter->port); } bson_copy_to (&uri->options, ©->options); bson_copy_to (&uri->credentials, ©->credentials); return copy; } const char * mongoc_uri_get_string (const mongoc_uri_t *uri) { BSON_ASSERT (uri); return uri->str; } const bson_t * mongoc_uri_get_read_prefs (const mongoc_uri_t *uri) { BSON_ASSERT (uri); return mongoc_read_prefs_get_tags(uri->read_prefs); } /* *-------------------------------------------------------------------------- * * mongoc_uri_unescape -- * * Escapes an UTF-8 encoded string containing URI escaped segments * such as %20. * * It is a programming error to call this function with a string * that is not UTF-8 encoded! * * Returns: * A newly allocated string that should be freed with bson_free(). * * Side effects: * None. * *-------------------------------------------------------------------------- */ char * mongoc_uri_unescape (const char *escaped_string) { bson_unichar_t c; bson_string_t *str; unsigned int hex = 0; const char *ptr; const char *end; size_t len; BSON_ASSERT (escaped_string); len = strlen(escaped_string); /* * Double check that this is a UTF-8 valid string. Bail out if necessary. */ if (!bson_utf8_validate(escaped_string, len, false)) { MONGOC_WARNING("%s(): escaped_string contains invalid UTF-8", BSON_FUNC); return NULL; } ptr = escaped_string; end = ptr + len; str = bson_string_new(NULL); for (; *ptr; ptr = bson_utf8_next_char(ptr)) { c = bson_utf8_get_char(ptr); switch (c) { case '%': if (((end - ptr) < 2) || !isxdigit(ptr[1]) || !isxdigit(ptr[2]) || #ifdef _MSC_VER (1 != sscanf_s(&ptr[1], "%02x", &hex)) || #else (1 != sscanf(&ptr[1], "%02x", &hex)) || #endif !isprint(hex)) { bson_string_free(str, true); return NULL; } bson_string_append_c(str, hex); ptr += 2; break; default: bson_string_append_unichar(str, c); break; } } return bson_string_free(str, false); } const mongoc_read_prefs_t * mongoc_uri_get_read_prefs_t (const mongoc_uri_t *uri) /* IN */ { BSON_ASSERT (uri); return uri->read_prefs; } const mongoc_read_concern_t * mongoc_uri_get_read_concern (const mongoc_uri_t *uri) /* IN */ { BSON_ASSERT (uri); return uri->read_concern; } const mongoc_write_concern_t * mongoc_uri_get_write_concern (const mongoc_uri_t *uri) /* IN */ { BSON_ASSERT (uri); return uri->write_concern; } bool mongoc_uri_get_ssl (const mongoc_uri_t *uri) /* IN */ { bson_iter_t iter; BSON_ASSERT (uri); return (bson_iter_init_find_case (&iter, &uri->options, "ssl") && BSON_ITER_HOLDS_BOOL (&iter) && bson_iter_bool (&iter)); } /* *-------------------------------------------------------------------------- * * mongoc_uri_get_option_as_int32 -- * * Checks if the URI 'option' is set and of correct type (int32). * The special value '0' is considered as "unset". * This is so users can provide * sprintf(mongodb://localhost/?option=%d, myvalue) style connection strings, * and still apply default values. * * If not set, or set to invalid type, 'fallback' is returned. * * NOTE: 'option' is case*in*sensitive. * * Returns: * The value of 'option' if available as int32 (and not 0), or 'fallback'. * *-------------------------------------------------------------------------- */ int32_t mongoc_uri_get_option_as_int32(const mongoc_uri_t *uri, const char *option, int32_t fallback) { const bson_t *options; bson_iter_t iter; int32_t retval = fallback; if ((options = mongoc_uri_get_options (uri)) && bson_iter_init_find_case (&iter, options, option) && BSON_ITER_HOLDS_INT32 (&iter)) { if (!(retval = bson_iter_int32(&iter))) { retval = fallback; } } return retval; } /* *-------------------------------------------------------------------------- * * mongoc_uri_set_option_as_int32 -- * * Sets a URI option 'after the fact'. Allows users to set individual * URI options without passing them as a connection string. * * Only allows a set of known options to be set. * @see mongoc_uri_option_is_int32 (). * * Does in-place-update of the option BSON if 'option' is already set. * Appends the option to the end otherwise. * * NOTE: If 'option' is already set, and is of invalid type, this * function will return false. * * NOTE: 'option' is case*in*sensitive. * * Returns: * true on successfully setting the option, false on failure. * *-------------------------------------------------------------------------- */ bool mongoc_uri_set_option_as_int32(mongoc_uri_t *uri, const char *option, int32_t value) { const bson_t *options; bson_iter_t iter; BSON_ASSERT (option); if (!mongoc_uri_option_is_int32 (option)) { return false; } if ((options = mongoc_uri_get_options (uri)) && bson_iter_init_find_case (&iter, options, option)) { if (BSON_ITER_HOLDS_INT32 (&iter)) { bson_iter_overwrite_int32 (&iter, value); return true; } else { return false; } } bson_append_int32(&uri->options, option, -1, value); return true; } /* *-------------------------------------------------------------------------- * * mongoc_uri_get_option_as_bool -- * * Checks if the URI 'option' is set and of correct type (bool). * * If not set, or set to invalid type, 'fallback' is returned. * * NOTE: 'option' is case*in*sensitive. * * Returns: * The value of 'option' if available as bool, or 'fallback'. * *-------------------------------------------------------------------------- */ bool mongoc_uri_get_option_as_bool (const mongoc_uri_t *uri, const char *option, bool fallback) { const bson_t *options; bson_iter_t iter; if ((options = mongoc_uri_get_options (uri)) && bson_iter_init_find_case (&iter, options, option) && BSON_ITER_HOLDS_BOOL (&iter)) { return bson_iter_bool (&iter); } return fallback; } /* *-------------------------------------------------------------------------- * * mongoc_uri_set_option_as_bool -- * * Sets a URI option 'after the fact'. Allows users to set individual * URI options without passing them as a connection string. * * Only allows a set of known options to be set. * @see mongoc_uri_option_is_bool (). * * Does in-place-update of the option BSON if 'option' is already set. * Appends the option to the end otherwise. * * NOTE: If 'option' is already set, and is of invalid type, this * function will return false. * * NOTE: 'option' is case*in*sensitive. * * Returns: * true on successfully setting the option, false on failure. * *-------------------------------------------------------------------------- */ bool mongoc_uri_set_option_as_bool(mongoc_uri_t *uri, const char *option, bool value) { const bson_t *options; bson_iter_t iter; BSON_ASSERT (option); if (!mongoc_uri_option_is_bool (option)) { return false; } if ((options = mongoc_uri_get_options (uri)) && bson_iter_init_find_case (&iter, options, option)) { if (BSON_ITER_HOLDS_BOOL (&iter)) { bson_iter_overwrite_bool (&iter, value); return true; } else { return false; } } bson_append_bool(&uri->options, option, -1, value); return true; } /* *-------------------------------------------------------------------------- * * mongoc_uri_get_option_as_utf8 -- * * Checks if the URI 'option' is set and of correct type (utf8). * * If not set, or set to invalid type, 'fallback' is returned. * * NOTE: 'option' is case*in*sensitive. * * Returns: * The value of 'option' if available as utf8, or 'fallback'. * *-------------------------------------------------------------------------- */ const char* mongoc_uri_get_option_as_utf8 (const mongoc_uri_t *uri, const char *option, const char *fallback) { const bson_t *options; bson_iter_t iter; if ((options = mongoc_uri_get_options (uri)) && bson_iter_init_find_case (&iter, options, option) && BSON_ITER_HOLDS_UTF8 (&iter)) { return bson_iter_utf8 (&iter, NULL); } return fallback; } /* *-------------------------------------------------------------------------- * * mongoc_uri_set_option_as_utf8 -- * * Sets a URI option 'after the fact'. Allows users to set individual * URI options without passing them as a connection string. * * Only allows a set of known options to be set. * @see mongoc_uri_option_is_utf8 (). * * If the option is not already set, this function will append it to the end * of the options bson. * NOTE: If the option is already set the entire options bson will be * overwritten, containing the new option=value (at the same position). * * NOTE: If 'option' is already set, and is of invalid type, this * function will return false. * * NOTE: 'option' must be valid utf8. * * NOTE: 'option' is case*in*sensitive. * * Returns: * true on successfully setting the option, false on failure. * *-------------------------------------------------------------------------- */ bool mongoc_uri_set_option_as_utf8(mongoc_uri_t *uri, const char *option, const char *value) { size_t len; BSON_ASSERT (option); len = strlen(value); if (!bson_utf8_validate (value, len, false)) { return false; } if (!mongoc_uri_option_is_utf8 (option)) { return false; } mongoc_uri_bson_append_or_replace_key (&uri->options, option, value); return true; } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-uri.h0000664000175000017500000000646412673034026022061 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_URI_H #define MONGOC_URI_H #if !defined (MONGOC_INSIDE) && !defined (MONGOC_COMPILATION) # error "Only can be included directly." #endif #include #include "mongoc-host-list.h" #include "mongoc-read-prefs.h" #include "mongoc-read-concern.h" #include "mongoc-write-concern.h" #ifndef MONGOC_DEFAULT_PORT # define MONGOC_DEFAULT_PORT 27017 #endif BSON_BEGIN_DECLS typedef struct _mongoc_uri_t mongoc_uri_t; mongoc_uri_t *mongoc_uri_copy (const mongoc_uri_t *uri); void mongoc_uri_destroy (mongoc_uri_t *uri); mongoc_uri_t *mongoc_uri_new (const char *uri_string) BSON_GNUC_WARN_UNUSED_RESULT; mongoc_uri_t *mongoc_uri_new_for_host_port (const char *hostname, uint16_t port) BSON_GNUC_WARN_UNUSED_RESULT; const mongoc_host_list_t *mongoc_uri_get_hosts (const mongoc_uri_t *uri); const char *mongoc_uri_get_database (const mongoc_uri_t *uri); const bson_t *mongoc_uri_get_options (const mongoc_uri_t *uri); const char *mongoc_uri_get_password (const mongoc_uri_t *uri); const bson_t *mongoc_uri_get_read_prefs (const mongoc_uri_t *uri) BSON_GNUC_DEPRECATED_FOR (mongoc_uri_get_read_prefs_t); const char *mongoc_uri_get_replica_set (const mongoc_uri_t *uri); const char *mongoc_uri_get_string (const mongoc_uri_t *uri); const char *mongoc_uri_get_username (const mongoc_uri_t *uri); const bson_t *mongoc_uri_get_credentials (const mongoc_uri_t *uri); const char *mongoc_uri_get_auth_source (const mongoc_uri_t *uri); const char *mongoc_uri_get_auth_mechanism (const mongoc_uri_t *uri); bool mongoc_uri_get_mechanism_properties (const mongoc_uri_t *uri, bson_t *properties); bool mongoc_uri_get_ssl (const mongoc_uri_t *uri); char *mongoc_uri_unescape (const char *escaped_string); const mongoc_read_prefs_t * mongoc_uri_get_read_prefs_t (const mongoc_uri_t *uri); const mongoc_write_concern_t *mongoc_uri_get_write_concern (const mongoc_uri_t *uri); const mongoc_read_concern_t *mongoc_uri_get_read_concern (const mongoc_uri_t *uri); BSON_END_DECLS #endif /* MONGOC_URI_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-util-private.h0000664000175000017500000000300512673034026023673 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_UTIL_PRIVATE_H #define MONGOC_UTIL_PRIVATE_H #if !defined (MONGOC_I_AM_A_DRIVER) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #include /* string comparison functions for Windows */ #ifdef _WIN32 # define strcasecmp _stricmp # define strncasecmp _strnicmp #endif /* Suppress CWE-252 ("Unchecked return value") warnings for things we can't deal with */ #if defined(__GNUC__) && __GNUC__ >= 4 # define _ignore_value(x) (({ __typeof__ (x) __x = (x); (void) __x; })) #else # define _ignore_value(x) ((void) (x)) #endif BSON_BEGIN_DECLS char *_mongoc_hex_md5 (const char *input); void _mongoc_usleep (int64_t usec); const char *_mongoc_get_command_name (const bson_t *command); void _mongoc_get_db_name (const char *ns, char *db /* OUT */); void _mongoc_bson_destroy_if_set (bson_t *bson); BSON_END_DECLS #endif /* MONGOC_UTIL_PRIVATE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-util.c0000664000175000017500000000426112673034026022223 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include "mongoc-util-private.h" #include "mongoc-client.h" char * _mongoc_hex_md5 (const char *input) { uint8_t digest[16]; bson_md5_t md5; char digest_str[33]; int i; bson_md5_init(&md5); bson_md5_append(&md5, (const uint8_t *)input, (uint32_t)strlen(input)); bson_md5_finish(&md5, digest); for (i = 0; i < sizeof digest; i++) { bson_snprintf(&digest_str[i*2], 3, "%02x", digest[i]); } digest_str[sizeof digest_str - 1] = '\0'; return bson_strdup(digest_str); } void _mongoc_usleep (int64_t usec) { #ifdef _WIN32 LARGE_INTEGER ft; HANDLE timer; BSON_ASSERT (usec >= 0); ft.QuadPart = -(10 * usec); timer = CreateWaitableTimer(NULL, true, NULL); SetWaitableTimer(timer, &ft, 0, NULL, NULL, 0); WaitForSingleObject(timer, INFINITE); CloseHandle(timer); #else BSON_ASSERT (usec >= 0); usleep ((useconds_t) usec); #endif } const char * _mongoc_get_command_name (const bson_t *command) { bson_iter_t iter; BSON_ASSERT (command); if (!bson_iter_init (&iter, command) || !bson_iter_next (&iter)) { return NULL; } return bson_iter_key (&iter); } void _mongoc_get_db_name (const char *ns, char *db /* OUT */) { size_t dblen; const char *dot; BSON_ASSERT (ns); dot = strstr (ns, "."); if (dot) { dblen = BSON_MIN (dot - ns + 1, MONGOC_NAMESPACE_MAX); bson_strncpy (db, ns, dblen); } else { bson_strncpy (db, ns, MONGOC_NAMESPACE_MAX); } } void _mongoc_bson_destroy_if_set (bson_t *bson) { if (bson) { bson_destroy (bson); } } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-version-functions.c0000664000175000017500000000330212673034026024734 0ustar jmikolajmikola/* * Copyright 2015 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "mongoc-version.h" #include "mongoc-version-functions.h" /** * mongoc_get_major_version: * * Helper function to return the runtime major version of the library. */ int mongoc_get_major_version (void) { return MONGOC_MAJOR_VERSION; } /** * mongoc_get_minor_version: * * Helper function to return the runtime minor version of the library. */ int mongoc_get_minor_version (void) { return MONGOC_MINOR_VERSION; } /** * mongoc_get_micro_version: * * Helper function to return the runtime micro version of the library. */ int mongoc_get_micro_version (void) { return MONGOC_MICRO_VERSION; } /** * mongoc_get_version: * * Helper function to return the runtime string version of the library. */ const char * mongoc_get_version (void) { return MONGOC_VERSION_S; } /** * mongoc_check_version: * * True if libmongoc's version is greater than or equal to the required * version. */ bool mongoc_check_version (int required_major, int required_minor, int required_micro) { return MONGOC_CHECK_VERSION(required_major, required_minor, required_micro); } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-version-functions.h0000664000175000017500000000221012673034026024736 0ustar jmikolajmikola/* * Copyright 2015 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if !defined (MONGOC_INSIDE) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #ifndef MONGOC_VERSION_FUNCTIONS_H #define MONGOC_VERSION_FUNCTIONS_H #include "bson.h" /* for "bool" */ int mongoc_get_major_version (void); int mongoc_get_minor_version (void); int mongoc_get_micro_version (void); const char *mongoc_get_version (void); bool mongoc_check_version (int required_major, int required_minor, int required_micro); #endif /* MONGOC_VERSION_FUNCTIONS_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-version.h0000664000175000017500000000465012673034026022742 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if !defined (MONGOC_INSIDE) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #ifndef MONGOC_VERSION_H #define MONGOC_VERSION_H /** * MONGOC_MAJOR_VERSION: * * MONGOC major version component (e.g. 1 if %MONGOC_VERSION is 1.2.3) */ #define MONGOC_MAJOR_VERSION (1) /** * MONGOC_MINOR_VERSION: * * MONGOC minor version component (e.g. 2 if %MONGOC_VERSION is 1.2.3) */ #define MONGOC_MINOR_VERSION (3) /** * MONGOC_MICRO_VERSION: * * MONGOC micro version component (e.g. 3 if %MONGOC_VERSION is 1.2.3) */ #define MONGOC_MICRO_VERSION (3) /** * MONGOC_PRERELEASE_VERSION: * * MONGOC prerelease version component (e.g. rc0 if %MONGOC_VERSION is 1.2.3-rc0) */ #define MONGOC_PRERELEASE_VERSION () /** * MONGOC_VERSION: * * MONGOC version. */ #define MONGOC_VERSION (1.3.3) /** * MONGOC_VERSION_S: * * MONGOC version, encoded as a string, useful for printing and * concatenation. */ #define MONGOC_VERSION_S "1.3.3" /** * MONGOC_VERSION_HEX: * * MONGOC version, encoded as an hexadecimal number, useful for * integer comparisons. */ #define MONGOC_VERSION_HEX (MONGOC_MAJOR_VERSION << 24 | \ MONGOC_MINOR_VERSION << 16 | \ MONGOC_MICRO_VERSION << 8) /** * MONGOC_CHECK_VERSION: * @major: required major version * @minor: required minor version * @micro: required micro version * * Compile-time version checking. Evaluates to %TRUE if the version * of MONGOC is greater than the required one. */ #define MONGOC_CHECK_VERSION(major,minor,micro) \ (MONGOC_MAJOR_VERSION > (major) || \ (MONGOC_MAJOR_VERSION == (major) && MONGOC_MINOR_VERSION > (minor)) || \ (MONGOC_MAJOR_VERSION == (major) && MONGOC_MINOR_VERSION == (minor) && \ MONGOC_MICRO_VERSION >= (micro))) #endif /* MONGOC_VERSION_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-version.h.in0000664000175000017500000000503012673034026023340 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if !defined (MONGOC_INSIDE) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #ifndef MONGOC_VERSION_H #define MONGOC_VERSION_H /** * MONGOC_MAJOR_VERSION: * * MONGOC major version component (e.g. 1 if %MONGOC_VERSION is 1.2.3) */ #define MONGOC_MAJOR_VERSION (@MONGOC_MAJOR_VERSION@) /** * MONGOC_MINOR_VERSION: * * MONGOC minor version component (e.g. 2 if %MONGOC_VERSION is 1.2.3) */ #define MONGOC_MINOR_VERSION (@MONGOC_MINOR_VERSION@) /** * MONGOC_MICRO_VERSION: * * MONGOC micro version component (e.g. 3 if %MONGOC_VERSION is 1.2.3) */ #define MONGOC_MICRO_VERSION (@MONGOC_MICRO_VERSION@) /** * MONGOC_PRERELEASE_VERSION: * * MONGOC prerelease version component (e.g. rc0 if %MONGOC_VERSION is 1.2.3-rc0) */ #define MONGOC_PRERELEASE_VERSION (@MONGOC_PRERELEASE_VERSION@) /** * MONGOC_VERSION: * * MONGOC version. */ #define MONGOC_VERSION (@MONGOC_VERSION@) /** * MONGOC_VERSION_S: * * MONGOC version, encoded as a string, useful for printing and * concatenation. */ #define MONGOC_VERSION_S "@MONGOC_VERSION@" /** * MONGOC_VERSION_HEX: * * MONGOC version, encoded as an hexadecimal number, useful for * integer comparisons. */ #define MONGOC_VERSION_HEX (MONGOC_MAJOR_VERSION << 24 | \ MONGOC_MINOR_VERSION << 16 | \ MONGOC_MICRO_VERSION << 8) /** * MONGOC_CHECK_VERSION: * @major: required major version * @minor: required minor version * @micro: required micro version * * Compile-time version checking. Evaluates to %TRUE if the version * of MONGOC is greater than the required one. */ #define MONGOC_CHECK_VERSION(major,minor,micro) \ (MONGOC_MAJOR_VERSION > (major) || \ (MONGOC_MAJOR_VERSION == (major) && MONGOC_MINOR_VERSION > (minor)) || \ (MONGOC_MAJOR_VERSION == (major) && MONGOC_MINOR_VERSION == (minor) && \ MONGOC_MICRO_VERSION >= (micro))) #endif /* MONGOC_VERSION_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-write-command-private.h0000664000175000017500000001402712673034026025472 0ustar jmikolajmikola/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_WRITE_COMMAND_PRIVATE_H #define MONGOC_WRITE_COMMAND_PRIVATE_H #if !defined (MONGOC_I_AM_A_DRIVER) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #include #include "mongoc-client.h" #include "mongoc-error.h" #include "mongoc-write-concern.h" #include "mongoc-server-stream-private.h" BSON_BEGIN_DECLS #define MONGOC_WRITE_COMMAND_DELETE 0 #define MONGOC_WRITE_COMMAND_INSERT 1 #define MONGOC_WRITE_COMMAND_UPDATE 2 typedef enum { MONGOC_BYPASS_DOCUMENT_VALIDATION_FALSE = 0, MONGOC_BYPASS_DOCUMENT_VALIDATION_TRUE = 1 << 0, MONGOC_BYPASS_DOCUMENT_VALIDATION_DEFAULT = 1 << 1, } mongoc_write_bypass_document_validation_t; struct _mongoc_bulk_write_flags_t { bool ordered; mongoc_write_bypass_document_validation_t bypass_document_validation; }; typedef struct { int type; uint32_t hint; bson_t *documents; uint32_t n_documents; mongoc_bulk_write_flags_t flags; union { struct { bool multi; } delete_; struct { bool allow_bulk_op_insert; } insert; } u; } mongoc_write_command_t; typedef struct { /* true after a legacy update prevents us from calculating nModified */ bool omit_nModified; uint32_t nInserted; uint32_t nMatched; uint32_t nModified; uint32_t nRemoved; uint32_t nUpserted; /* like [{"index": int, "_id": value}, ...] */ bson_t writeErrors; /* like [{"index": int, "code": int, "errmsg": str}, ...] */ bson_t upserted; /* like [{"code": 64, "errmsg": "duplicate"}, ...] */ uint32_t n_writeConcernErrors; bson_t writeConcernErrors; bool failed; bson_error_t error; uint32_t upsert_append_count; } mongoc_write_result_t; void _mongoc_write_command_destroy (mongoc_write_command_t *command); void _mongoc_write_command_init_insert (mongoc_write_command_t *command, const bson_t *document, mongoc_bulk_write_flags_t flags, bool allow_bulk_op_insert); void _mongoc_write_command_init_delete (mongoc_write_command_t *command, const bson_t *selectors, bool multi, mongoc_bulk_write_flags_t flags); void _mongoc_write_command_init_update (mongoc_write_command_t *command, const bson_t *selector, const bson_t *update, bool upsert, bool multi, mongoc_bulk_write_flags_t flags); void _mongoc_write_command_insert_append (mongoc_write_command_t *command, const bson_t *document); void _mongoc_write_command_update_append (mongoc_write_command_t *command, const bson_t *selector, const bson_t *update, bool upsert, bool multi); void _mongoc_write_command_delete_append (mongoc_write_command_t *command, const bson_t *selector); void _mongoc_write_command_execute (mongoc_write_command_t *command, mongoc_client_t *client, mongoc_server_stream_t *server_stream, const char *database, const char *collection, const mongoc_write_concern_t *write_concern, uint32_t offset, mongoc_write_result_t *result); void _mongoc_write_result_init (mongoc_write_result_t *result); void _mongoc_write_result_merge (mongoc_write_result_t *result, mongoc_write_command_t *command, const bson_t *reply, uint32_t offset); void _mongoc_write_result_merge_legacy (mongoc_write_result_t *result, mongoc_write_command_t *command, const bson_t *reply, mongoc_error_code_t default_code, uint32_t offset); bool _mongoc_write_result_complete (mongoc_write_result_t *result, bson_t *reply, bson_error_t *error); void _mongoc_write_result_destroy (mongoc_write_result_t *result); BSON_END_DECLS #endif /* MONGOC_WRITE_COMMAND_PRIVATE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-write-command.c0000664000175000017500000013604512673034026024022 0ustar jmikolajmikola/* * Copyright 2014 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include "mongoc-client-private.h" #include "mongoc-error.h" #include "mongoc-trace.h" #include "mongoc-write-command-private.h" #include "mongoc-write-concern-private.h" #include "mongoc-util-private.h" /* * TODO: * * - Remove error parameter to ops, favor result->error. */ #define WRITE_CONCERN_DOC(wc) \ (wc && _mongoc_write_concern_needs_gle ((wc))) ? \ (_mongoc_write_concern_get_bson((mongoc_write_concern_t*)(wc))) : \ (&gEmptyWriteConcern) typedef void (*mongoc_write_op_t) (mongoc_write_command_t *command, mongoc_client_t *client, mongoc_server_stream_t *server_stream, const char *database, const char *collection, const mongoc_write_concern_t *write_concern, uint32_t offset, mongoc_write_result_t *result, bson_error_t *error); static bson_t gEmptyWriteConcern = BSON_INITIALIZER; /* indexed by MONGOC_WRITE_COMMAND_DELETE, INSERT, UPDATE */ static const char *gCommandNames[] = { "delete", "insert", "update"}; static const char *gCommandFields[] = { "deletes", "documents", "updates"}; static const uint32_t gCommandFieldLens[] = { 7, 9, 7 }; static int32_t _mongoc_write_result_merge_arrays (uint32_t offset, mongoc_write_result_t *result, bson_t *dest, bson_iter_t *iter); void _mongoc_write_command_insert_append (mongoc_write_command_t *command, const bson_t *document) { const char *key; bson_iter_t iter; bson_oid_t oid; bson_t tmp; char keydata [16]; ENTRY; BSON_ASSERT (command); BSON_ASSERT (command->type == MONGOC_WRITE_COMMAND_INSERT); BSON_ASSERT (document); BSON_ASSERT (document->len >= 5); key = NULL; bson_uint32_to_string (command->n_documents, &key, keydata, sizeof keydata); BSON_ASSERT (key); /* * If the document does not contain an "_id" field, we need to generate * a new oid for "_id". */ if (!bson_iter_init_find (&iter, document, "_id")) { bson_init (&tmp); bson_oid_init (&oid, NULL); BSON_APPEND_OID (&tmp, "_id", &oid); bson_concat (&tmp, document); BSON_APPEND_DOCUMENT (command->documents, key, &tmp); bson_destroy (&tmp); } else { BSON_APPEND_DOCUMENT (command->documents, key, document); } command->n_documents++; EXIT; } void _mongoc_write_command_update_append (mongoc_write_command_t *command, const bson_t *selector, const bson_t *update, bool upsert, bool multi) { const char *key; char keydata [16]; bson_t doc; ENTRY; BSON_ASSERT (command); BSON_ASSERT (command->type == MONGOC_WRITE_COMMAND_UPDATE); BSON_ASSERT (selector && update); bson_init (&doc); BSON_APPEND_DOCUMENT (&doc, "q", selector); BSON_APPEND_DOCUMENT (&doc, "u", update); BSON_APPEND_BOOL (&doc, "upsert", upsert); BSON_APPEND_BOOL (&doc, "multi", multi); key = NULL; bson_uint32_to_string (command->n_documents, &key, keydata, sizeof keydata); BSON_ASSERT (key); BSON_APPEND_DOCUMENT (command->documents, key, &doc); command->n_documents++; bson_destroy (&doc); EXIT; } void _mongoc_write_command_delete_append (mongoc_write_command_t *command, const bson_t *selector) { const char *key; char keydata [16]; bson_t doc; ENTRY; BSON_ASSERT (command); BSON_ASSERT (command->type == MONGOC_WRITE_COMMAND_DELETE); BSON_ASSERT (selector); BSON_ASSERT (selector->len >= 5); bson_init (&doc); BSON_APPEND_DOCUMENT (&doc, "q", selector); BSON_APPEND_INT32 (&doc, "limit", command->u.delete_.multi ? 0 : 1); key = NULL; bson_uint32_to_string (command->n_documents, &key, keydata, sizeof keydata); BSON_ASSERT (key); BSON_APPEND_DOCUMENT (command->documents, key, &doc); command->n_documents++; bson_destroy (&doc); EXIT; } void _mongoc_write_command_init_insert (mongoc_write_command_t *command, /* IN */ const bson_t *document, /* IN */ mongoc_bulk_write_flags_t flags, /* IN */ bool allow_bulk_op_insert) /* IN */ { ENTRY; BSON_ASSERT (command); command->type = MONGOC_WRITE_COMMAND_INSERT; command->documents = bson_new (); command->n_documents = 0; command->flags = flags; command->u.insert.allow_bulk_op_insert = (uint8_t)allow_bulk_op_insert; command->hint = 0; /* must handle NULL document from mongoc_collection_insert_bulk */ if (document) { _mongoc_write_command_insert_append (command, document); } EXIT; } void _mongoc_write_command_init_delete (mongoc_write_command_t *command, /* IN */ const bson_t *selector, /* IN */ bool multi, /* IN */ mongoc_bulk_write_flags_t flags) /* IN */ { ENTRY; BSON_ASSERT (command); BSON_ASSERT (selector); command->type = MONGOC_WRITE_COMMAND_DELETE; command->documents = bson_new (); command->n_documents = 0; command->u.delete_.multi = (uint8_t)multi; command->flags = flags; command->hint = 0; _mongoc_write_command_delete_append (command, selector); EXIT; } void _mongoc_write_command_init_update (mongoc_write_command_t *command, /* IN */ const bson_t *selector, /* IN */ const bson_t *update, /* IN */ bool upsert, /* IN */ bool multi, /* IN */ mongoc_bulk_write_flags_t flags) /* IN */ { ENTRY; BSON_ASSERT (command); BSON_ASSERT (selector); BSON_ASSERT (update); command->type = MONGOC_WRITE_COMMAND_UPDATE; command->documents = bson_new (); command->n_documents = 0; command->flags = flags; command->hint = 0; _mongoc_write_command_update_append (command, selector, update, upsert, multi); EXIT; } static void _mongoc_write_command_delete_legacy (mongoc_write_command_t *command, mongoc_client_t *client, mongoc_server_stream_t *server_stream, const char *database, const char *collection, const mongoc_write_concern_t *write_concern, uint32_t offset, mongoc_write_result_t *result, bson_error_t *error) { const uint8_t *data; mongoc_rpc_t rpc; bson_iter_t iter; bson_iter_t q_iter; uint32_t len; bson_t *gle = NULL; char ns [MONGOC_NAMESPACE_MAX + 1]; bool r; ENTRY; BSON_ASSERT (command); BSON_ASSERT (client); BSON_ASSERT (database); BSON_ASSERT (server_stream); BSON_ASSERT (collection); r = bson_iter_init (&iter, command->documents); if (!r) { BSON_ASSERT (false); EXIT; } if (!command->n_documents || !bson_iter_next (&iter)) { bson_set_error (error, MONGOC_ERROR_COLLECTION, MONGOC_ERROR_COLLECTION_DELETE_FAILED, "Cannot do an empty delete."); result->failed = true; EXIT; } bson_snprintf (ns, sizeof ns, "%s.%s", database, collection); do { /* the document is like { "q": { }, limit: <0 or 1> } */ r = (bson_iter_recurse (&iter, &q_iter) && bson_iter_find (&q_iter, "q") && BSON_ITER_HOLDS_DOCUMENT (&q_iter)); if (!r) { BSON_ASSERT (false); EXIT; } bson_iter_document (&q_iter, &len, &data); BSON_ASSERT (data); BSON_ASSERT (len >= 5); rpc.delete_.msg_len = 0; rpc.delete_.request_id = 0; rpc.delete_.response_to = 0; rpc.delete_.opcode = MONGOC_OPCODE_DELETE; rpc.delete_.zero = 0; rpc.delete_.collection = ns; rpc.delete_.flags = command->u.delete_.multi ? MONGOC_DELETE_NONE : MONGOC_DELETE_SINGLE_REMOVE; rpc.delete_.selector = data; if (!mongoc_cluster_sendv_to_server (&client->cluster, &rpc, 1, server_stream, write_concern, error)) { result->failed = true; EXIT; } if (_mongoc_write_concern_needs_gle (write_concern)) { if (!_mongoc_client_recv_gle (client, server_stream, &gle, error)) { result->failed = true; EXIT; } _mongoc_write_result_merge_legacy ( result, command, gle, MONGOC_ERROR_COLLECTION_DELETE_FAILED, offset); offset++; bson_destroy (gle); } } while (bson_iter_next (&iter)); EXIT; } /* *------------------------------------------------------------------------- * * too_large_error -- * * Fill a bson_error_t and optional bson_t with error info after * receiving a document for bulk insert, update, or remove that is * larger than max_bson_size. * * "err_doc" should be NULL or an empty initialized bson_t. * * Returns: * None. * * Side effects: * "error" and optionally "err_doc" are filled out. * *------------------------------------------------------------------------- */ static void too_large_error (bson_error_t *error, int32_t idx, int32_t len, int32_t max_bson_size, bson_t *err_doc) { /* MongoDB 2.6 uses code 2 for "too large". TODO: see CDRIVER-644 */ const int code = 2; bson_set_error (error, MONGOC_ERROR_BSON, code, "Document %u is too large for the cluster. " "Document is %u bytes, max is %d.", idx, len, max_bson_size); if (err_doc) { BSON_APPEND_INT32 (err_doc, "index", idx); BSON_APPEND_UTF8 (err_doc, "err", error->message); BSON_APPEND_INT32 (err_doc, "code", code); } } static void _mongoc_write_command_insert_legacy (mongoc_write_command_t *command, mongoc_client_t *client, mongoc_server_stream_t *server_stream, const char *database, const char *collection, const mongoc_write_concern_t *write_concern, uint32_t offset, mongoc_write_result_t *result, bson_error_t *error) { uint32_t current_offset; mongoc_iovec_t *iov; const uint8_t *data; mongoc_rpc_t rpc; bson_iter_t iter; uint32_t len; bson_t *gle = NULL; uint32_t size = 0; bool has_more; char ns [MONGOC_NAMESPACE_MAX + 1]; bool r; uint32_t n_docs_in_batch; uint32_t idx = 0; int32_t max_msg_size; int32_t max_bson_obj_size; bool singly; ENTRY; BSON_ASSERT (command); BSON_ASSERT (client); BSON_ASSERT (database); BSON_ASSERT (server_stream); BSON_ASSERT (collection); BSON_ASSERT (command->type == MONGOC_WRITE_COMMAND_INSERT); current_offset = offset; max_bson_obj_size = mongoc_server_stream_max_bson_obj_size (server_stream); max_msg_size = mongoc_server_stream_max_msg_size (server_stream); singly = !command->u.insert.allow_bulk_op_insert; r = bson_iter_init (&iter, command->documents); if (!r) { BSON_ASSERT (false); EXIT; } if (!command->n_documents || !bson_iter_next (&iter)) { bson_set_error (error, MONGOC_ERROR_COLLECTION, MONGOC_ERROR_COLLECTION_INSERT_FAILED, "Cannot do an empty insert."); result->failed = true; EXIT; } bson_snprintf (ns, sizeof ns, "%s.%s", database, collection); iov = (mongoc_iovec_t *)bson_malloc ((sizeof *iov) * command->n_documents); again: has_more = false; n_docs_in_batch = 0; size = (uint32_t)(sizeof (mongoc_rpc_header_t) + 4 + strlen (database) + 1 + strlen (collection) + 1); do { BSON_ASSERT (BSON_ITER_HOLDS_DOCUMENT (&iter)); BSON_ASSERT (n_docs_in_batch <= idx); BSON_ASSERT (idx < command->n_documents); bson_iter_document (&iter, &len, &data); BSON_ASSERT (data); BSON_ASSERT (len >= 5); if (len > max_bson_obj_size) { /* document is too large */ bson_t write_err_doc = BSON_INITIALIZER; too_large_error (error, idx, len, max_bson_obj_size, &write_err_doc); _mongoc_write_result_merge_legacy ( result, command, &write_err_doc, MONGOC_ERROR_COLLECTION_INSERT_FAILED, offset + idx); bson_destroy (&write_err_doc); if (command->flags.ordered) { /* send the batch so far (if any) and return the error */ break; } } else if ((n_docs_in_batch == 1 && singly) || size > (max_msg_size - len)) { /* batch is full, send it and then start the next batch */ has_more = true; break; } else { /* add document to batch and continue building the batch */ iov[n_docs_in_batch].iov_base = (void *) data; iov[n_docs_in_batch].iov_len = len; size += len; n_docs_in_batch++; } idx++; } while (bson_iter_next (&iter)); if (n_docs_in_batch) { rpc.insert.msg_len = 0; rpc.insert.request_id = 0; rpc.insert.response_to = 0; rpc.insert.opcode = MONGOC_OPCODE_INSERT; rpc.insert.flags = ( (command->flags.ordered) ? MONGOC_INSERT_NONE : MONGOC_INSERT_CONTINUE_ON_ERROR); rpc.insert.collection = ns; rpc.insert.documents = iov; rpc.insert.n_documents = n_docs_in_batch; if (!mongoc_cluster_sendv_to_server (&client->cluster, &rpc, 1, server_stream, write_concern, error)) { result->failed = true; GOTO (cleanup); } if (_mongoc_write_concern_needs_gle (write_concern)) { bool err = false; bson_iter_t citer; if (!_mongoc_client_recv_gle (client, server_stream, &gle, error)) { result->failed = true; GOTO (cleanup); } err = (bson_iter_init_find (&citer, gle, "err") && bson_iter_as_bool (&citer)); /* * Overwrite the "n" field since it will be zero. Otherwise, our * merge_legacy code will not know how many we tried in this batch. */ if (!err && bson_iter_init_find (&citer, gle, "n") && BSON_ITER_HOLDS_INT32 (&citer) && !bson_iter_int32 (&citer)) { bson_iter_overwrite_int32 (&citer, n_docs_in_batch); } } } cleanup: if (gle) { _mongoc_write_result_merge_legacy ( result, command, gle, MONGOC_ERROR_COLLECTION_INSERT_FAILED, current_offset); current_offset = offset + idx; bson_destroy (gle); gle = NULL; } if (has_more) { GOTO (again); } bson_free (iov); EXIT; } void _empty_error (mongoc_write_command_t *command, bson_error_t *error) { static const uint32_t codes[] = { MONGOC_ERROR_COLLECTION_DELETE_FAILED, MONGOC_ERROR_COLLECTION_INSERT_FAILED, MONGOC_ERROR_COLLECTION_UPDATE_FAILED }; bson_set_error (error, MONGOC_ERROR_COLLECTION, codes[command->type], "Cannot do an empty %s", gCommandNames[command->type]); } bool _mongoc_write_command_will_overflow (uint32_t len_so_far, uint32_t document_len, uint32_t n_documents_written, int32_t max_bson_size, int32_t max_write_batch_size) { /* max BSON object size + 16k bytes. * server guarantees there is enough room: SERVER-10643 */ int32_t max_cmd_size = max_bson_size + 16384; BSON_ASSERT (max_bson_size); if (len_so_far + document_len > max_cmd_size) { return true; } else if (max_write_batch_size > 0 && n_documents_written >= max_write_batch_size) { return true; } return false; } static void _mongoc_write_command_update_legacy (mongoc_write_command_t *command, mongoc_client_t *client, mongoc_server_stream_t *server_stream, const char *database, const char *collection, const mongoc_write_concern_t *write_concern, uint32_t offset, mongoc_write_result_t *result, bson_error_t *error) { mongoc_rpc_t rpc; bson_iter_t iter, subiter, subsubiter; bson_t doc; bool has_update, has_selector, is_upsert; bson_t update, selector; bson_t *gle = NULL; const uint8_t *data = NULL; uint32_t len = 0; size_t err_offset; bool val = false; char ns [MONGOC_NAMESPACE_MAX + 1]; int32_t affected = 0; int vflags = (BSON_VALIDATE_UTF8 | BSON_VALIDATE_UTF8_ALLOW_NULL | BSON_VALIDATE_DOLLAR_KEYS | BSON_VALIDATE_DOT_KEYS); ENTRY; BSON_ASSERT (command); BSON_ASSERT (client); BSON_ASSERT (database); BSON_ASSERT (server_stream); BSON_ASSERT (collection); bson_iter_init (&iter, command->documents); while (bson_iter_next (&iter)) { if (bson_iter_recurse (&iter, &subiter) && bson_iter_find (&subiter, "u") && BSON_ITER_HOLDS_DOCUMENT (&subiter)) { bson_iter_document (&subiter, &len, &data); bson_init_static (&doc, data, len); if (bson_iter_init (&subsubiter, &doc) && bson_iter_next (&subsubiter) && (bson_iter_key (&subsubiter) [0] != '$') && !bson_validate (&doc, (bson_validate_flags_t)vflags, &err_offset)) { result->failed = true; bson_set_error (error, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, "update document is corrupt or contains " "invalid keys including $ or ."); EXIT; } } else { result->failed = true; bson_set_error (error, MONGOC_ERROR_BSON, MONGOC_ERROR_BSON_INVALID, "updates is malformed."); EXIT; } } bson_snprintf (ns, sizeof ns, "%s.%s", database, collection); bson_iter_init (&iter, command->documents); while (bson_iter_next (&iter)) { rpc.update.msg_len = 0; rpc.update.request_id = 0; rpc.update.response_to = 0; rpc.update.opcode = MONGOC_OPCODE_UPDATE; rpc.update.zero = 0; rpc.update.collection = ns; rpc.update.flags = MONGOC_UPDATE_NONE; has_update = false; has_selector = false; is_upsert = false; bson_iter_recurse (&iter, &subiter); while (bson_iter_next (&subiter)) { if (strcmp (bson_iter_key (&subiter), "u") == 0) { bson_iter_document (&subiter, &len, &data); rpc.update.update = data; bson_init_static (&update, data, len); has_update = true; } else if (strcmp (bson_iter_key (&subiter), "q") == 0) { bson_iter_document (&subiter, &len, &data); rpc.update.selector = data; bson_init_static (&selector, data, len); has_selector = true; } else if (strcmp (bson_iter_key (&subiter), "multi") == 0) { val = bson_iter_bool (&subiter); if (val) { rpc.update.flags = (mongoc_update_flags_t)( rpc.update.flags | MONGOC_UPDATE_MULTI_UPDATE); } } else if (strcmp (bson_iter_key (&subiter), "upsert") == 0) { val = bson_iter_bool (&subiter); if (val) { rpc.update.flags = (mongoc_update_flags_t)( rpc.update.flags | MONGOC_UPDATE_UPSERT); } is_upsert = true; } } if (!mongoc_cluster_sendv_to_server (&client->cluster, &rpc, 1, server_stream, write_concern, error)) { result->failed = true; EXIT; } if (_mongoc_write_concern_needs_gle (write_concern)) { if (!_mongoc_client_recv_gle (client, server_stream, &gle, error)) { result->failed = true; EXIT; } if (bson_iter_init_find (&subiter, gle, "n") && BSON_ITER_HOLDS_INT32 (&subiter)) { affected = bson_iter_int32 (&subiter); } /* * CDRIVER-372: * * Versions of MongoDB before 2.6 don't return the _id for an * upsert if _id is not an ObjectId. */ if (is_upsert && affected && !bson_iter_init_find (&subiter, gle, "upserted") && bson_iter_init_find (&subiter, gle, "updatedExisting") && BSON_ITER_HOLDS_BOOL (&subiter) && !bson_iter_bool (&subiter)) { if (has_update && bson_iter_init_find (&subiter, &update, "_id")) { _ignore_value (bson_append_iter (gle, "upserted", 8, &subiter)); } else if (has_selector && bson_iter_init_find (&subiter, &selector, "_id")) { _ignore_value (bson_append_iter (gle, "upserted", 8, &subiter)); } } _mongoc_write_result_merge_legacy ( result, command, gle, MONGOC_ERROR_COLLECTION_UPDATE_FAILED, offset); offset++; bson_destroy (gle); } } EXIT; } static mongoc_write_op_t gLegacyWriteOps[3] = { _mongoc_write_command_delete_legacy, _mongoc_write_command_insert_legacy, _mongoc_write_command_update_legacy }; static void _mongoc_write_command(mongoc_write_command_t *command, mongoc_client_t *client, mongoc_server_stream_t *server_stream, const char *database, const char *collection, const mongoc_write_concern_t *write_concern, uint32_t offset, mongoc_write_result_t *result, bson_error_t *error) { const uint8_t *data; bson_iter_t iter; const char *key; uint32_t len = 0; bson_t tmp; bson_t ar; bson_t cmd; bson_t reply; char str [16]; bool has_more; bool ret = false; uint32_t i; int32_t max_bson_obj_size; int32_t max_write_batch_size; int32_t min_wire_version; uint32_t overhead; uint32_t key_len; ENTRY; BSON_ASSERT (command); BSON_ASSERT (client); BSON_ASSERT (database); BSON_ASSERT (server_stream); BSON_ASSERT (collection); max_bson_obj_size = mongoc_server_stream_max_bson_obj_size (server_stream); max_write_batch_size = mongoc_server_stream_max_write_batch_size (server_stream); /* * If we have an unacknowledged write and the server supports the legacy * opcodes, then submit the legacy opcode so we don't need to wait for * a response from the server. */ min_wire_version = server_stream->sd->min_wire_version; if ((min_wire_version == 0) && !_mongoc_write_concern_needs_gle (write_concern)) { if (command->flags.bypass_document_validation != MONGOC_BYPASS_DOCUMENT_VALIDATION_DEFAULT) { bson_set_error (error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "Cannot set bypassDocumentValidation for unacknowledged writes"); EXIT; } gLegacyWriteOps[command->type] (command, client, server_stream, database, collection, write_concern, offset, result, error); EXIT; } if (!command->n_documents || !bson_iter_init (&iter, command->documents) || !bson_iter_next (&iter)) { _empty_error (command, error); result->failed = true; EXIT; } again: bson_init (&cmd); has_more = false; i = 0; BSON_APPEND_UTF8 (&cmd, gCommandNames[command->type], collection); BSON_APPEND_DOCUMENT (&cmd, "writeConcern", WRITE_CONCERN_DOC (write_concern)); BSON_APPEND_BOOL (&cmd, "ordered", command->flags.ordered); if (command->flags.bypass_document_validation != MONGOC_BYPASS_DOCUMENT_VALIDATION_DEFAULT) { BSON_APPEND_BOOL (&cmd, "bypassDocumentValidation", !!command->flags.bypass_document_validation); } /* 1 byte to specify array type, 1 byte for field name's null terminator */ overhead = cmd.len + 2 + gCommandFieldLens[command->type]; if (!_mongoc_write_command_will_overflow (overhead, command->documents->len, command->n_documents, max_bson_obj_size, max_write_batch_size)) { /* copy the whole documents buffer as e.g. "updates": [...] */ bson_append_array (&cmd, gCommandFields[command->type], gCommandFieldLens[command->type], command->documents); i = command->n_documents; } else { bson_append_array_begin (&cmd, gCommandFields[command->type], gCommandFieldLens[command->type], &ar); do { if (!BSON_ITER_HOLDS_DOCUMENT (&iter)) { BSON_ASSERT (false); } bson_iter_document (&iter, &len, &data); key_len = (uint32_t) bson_uint32_to_string (i, &key, str, sizeof str); if (_mongoc_write_command_will_overflow (overhead, key_len + len + 2 + ar.len, i, max_bson_obj_size, max_write_batch_size)) { has_more = true; break; } if (!bson_init_static (&tmp, data, len)) { BSON_ASSERT (false); } BSON_APPEND_DOCUMENT (&ar, key, &tmp); bson_destroy (&tmp); i++; } while (bson_iter_next (&iter)); bson_append_array_end (&cmd, &ar); } if (!i) { too_large_error (error, i, len, max_bson_obj_size, NULL); result->failed = true; ret = false; } else { ret = mongoc_cluster_run_command (&client->cluster, server_stream->stream, server_stream->sd->id, MONGOC_QUERY_NONE, database, &cmd, &reply, error); if (!ret) { result->failed = true; } _mongoc_write_result_merge (result, command, &reply, offset); offset += i; bson_destroy (&reply); } bson_destroy (&cmd); if (has_more && (ret || !command->flags.ordered)) { GOTO (again); } EXIT; } void _mongoc_write_command_execute (mongoc_write_command_t *command, /* IN */ mongoc_client_t *client, /* IN */ mongoc_server_stream_t *server_stream, /* IN */ const char *database, /* IN */ const char *collection, /* IN */ const mongoc_write_concern_t *write_concern, /* IN */ uint32_t offset, /* IN */ mongoc_write_result_t *result) /* OUT */ { ENTRY; BSON_ASSERT (command); BSON_ASSERT (client); BSON_ASSERT (server_stream); BSON_ASSERT (database); BSON_ASSERT (collection); BSON_ASSERT (result); if (!write_concern) { write_concern = client->write_concern; } if (!_mongoc_write_concern_is_valid(write_concern)) { bson_set_error (&result->error, MONGOC_ERROR_COMMAND, MONGOC_ERROR_COMMAND_INVALID_ARG, "The write concern is invalid."); result->failed = true; EXIT; } if (!command->hint) { command->hint = server_stream->sd->id; } else { BSON_ASSERT (command->hint == server_stream->sd->id); } if (server_stream->sd->max_wire_version >= WIRE_VERSION_WRITE_CMD) { _mongoc_write_command (command, client, server_stream, database, collection, write_concern, offset, result, &result->error); } else { gLegacyWriteOps[command->type] (command, client, server_stream, database, collection, write_concern, offset, result, &result->error); } EXIT; } void _mongoc_write_command_destroy (mongoc_write_command_t *command) { ENTRY; if (command) { bson_destroy (command->documents); } EXIT; } void _mongoc_write_result_init (mongoc_write_result_t *result) /* IN */ { ENTRY; BSON_ASSERT (result); memset (result, 0, sizeof *result); bson_init (&result->upserted); bson_init (&result->writeConcernErrors); bson_init (&result->writeErrors); EXIT; } void _mongoc_write_result_destroy (mongoc_write_result_t *result) { ENTRY; BSON_ASSERT (result); bson_destroy (&result->upserted); bson_destroy (&result->writeConcernErrors); bson_destroy (&result->writeErrors); EXIT; } static void _mongoc_write_result_append_upsert (mongoc_write_result_t *result, int32_t idx, const bson_value_t *value) { bson_t child; const char *keyptr = NULL; char key[12]; int len; BSON_ASSERT (result); BSON_ASSERT (value); len = (int)bson_uint32_to_string (result->upsert_append_count, &keyptr, key, sizeof key); bson_append_document_begin (&result->upserted, keyptr, len, &child); BSON_APPEND_INT32 (&child, "index", idx); BSON_APPEND_VALUE (&child, "_id", value); bson_append_document_end (&result->upserted, &child); result->upsert_append_count++; } static void _append_write_concern_err_legacy (mongoc_write_result_t *result, const char *err, int32_t code) { char str[16]; const char *key; size_t keylen; bson_t write_concern_error; /* don't set result->failed; record the write concern err and continue */ keylen = bson_uint32_to_string (result->n_writeConcernErrors, &key, str, sizeof str); BSON_ASSERT (keylen < INT_MAX); bson_append_document_begin (&result->writeConcernErrors, key, (int) keylen, &write_concern_error); bson_append_int32 (&write_concern_error, "code", 4, code); bson_append_utf8 (&write_concern_error, "errmsg", 6, err, -1); bson_append_document_end (&result->writeConcernErrors, &write_concern_error); result->n_writeConcernErrors++; } static void _append_write_err_legacy (mongoc_write_result_t *result, const char *err, int32_t code, uint32_t offset) { bson_t holder, write_errors, child; bson_iter_t iter; BSON_ASSERT (code > 0); bson_set_error (&result->error, MONGOC_ERROR_COLLECTION, (uint32_t) code, "%s", err); /* stop processing, if result->ordered */ result->failed = true; bson_init (&holder); bson_append_array_begin (&holder, "0", 1, &write_errors); bson_append_document_begin (&write_errors, "0", 1, &child); /* set error's "index" to 0; fixed up in _mongoc_write_result_merge_arrays */ bson_append_int32 (&child, "index", 5, 0); bson_append_int32 (&child, "code", 4, code); bson_append_utf8 (&child, "errmsg", 6, err, -1); bson_append_document_end (&write_errors, &child); bson_append_array_end (&holder, &write_errors); bson_iter_init (&iter, &holder); bson_iter_next (&iter); _mongoc_write_result_merge_arrays (offset, result, &result->writeErrors, &iter); bson_destroy (&holder); } void _mongoc_write_result_merge_legacy (mongoc_write_result_t *result, /* IN */ mongoc_write_command_t *command, /* IN */ const bson_t *reply, /* IN */ mongoc_error_code_t default_code, uint32_t offset) { const bson_value_t *value; bson_iter_t iter; bson_iter_t ar; bson_iter_t citer; const char *err = NULL; int32_t code = 0; int32_t n = 0; int32_t upsert_idx = 0; ENTRY; BSON_ASSERT (result); BSON_ASSERT (reply); if (bson_iter_init_find (&iter, reply, "n") && BSON_ITER_HOLDS_INT32 (&iter)) { n = bson_iter_int32 (&iter); } if (bson_iter_init_find (&iter, reply, "err") && BSON_ITER_HOLDS_UTF8 (&iter)) { err = bson_iter_utf8 (&iter, NULL); } if (bson_iter_init_find (&iter, reply, "code") && BSON_ITER_HOLDS_INT32 (&iter)) { code = bson_iter_int32 (&iter); } if (code || err) { if (!err) { err = "unknown error"; } if (bson_iter_init_find (&iter, reply, "wtimeout") && bson_iter_as_bool (&iter)) { if (!code) { code = (int32_t) MONGOC_ERROR_WRITE_CONCERN_ERROR; } _append_write_concern_err_legacy (result, err, code); } else { if (!code) { code = (int32_t) default_code; } _append_write_err_legacy (result, err, code, offset); } } switch (command->type) { case MONGOC_WRITE_COMMAND_INSERT: if (n) { result->nInserted += n; } break; case MONGOC_WRITE_COMMAND_DELETE: result->nRemoved += n; break; case MONGOC_WRITE_COMMAND_UPDATE: if (bson_iter_init_find (&iter, reply, "upserted") && !BSON_ITER_HOLDS_ARRAY (&iter)) { result->nUpserted += n; value = bson_iter_value (&iter); _mongoc_write_result_append_upsert (result, offset, value); } else if (bson_iter_init_find (&iter, reply, "upserted") && BSON_ITER_HOLDS_ARRAY (&iter)) { result->nUpserted += n; if (bson_iter_recurse (&iter, &ar)) { while (bson_iter_next (&ar)) { if (BSON_ITER_HOLDS_DOCUMENT (&ar) && bson_iter_recurse (&ar, &citer) && bson_iter_find (&citer, "_id")) { value = bson_iter_value (&citer); _mongoc_write_result_append_upsert (result, offset + upsert_idx, value); upsert_idx++; } } } } else if ((n == 1) && bson_iter_init_find (&iter, reply, "updatedExisting") && BSON_ITER_HOLDS_BOOL (&iter) && !bson_iter_bool (&iter)) { result->nUpserted += n; } else { result->nMatched += n; } break; default: break; } result->omit_nModified = true; EXIT; } static int32_t _mongoc_write_result_merge_arrays (uint32_t offset, mongoc_write_result_t *result, /* IN */ bson_t *dest, /* IN */ bson_iter_t *iter) /* IN */ { const bson_value_t *value; bson_iter_t ar; bson_iter_t citer; int32_t idx; int32_t count = 0; int32_t aridx; bson_t child; const char *keyptr = NULL; char key[12]; int len; ENTRY; BSON_ASSERT (result); BSON_ASSERT (dest); BSON_ASSERT (iter); BSON_ASSERT (BSON_ITER_HOLDS_ARRAY (iter)); aridx = bson_count_keys (dest); if (bson_iter_recurse (iter, &ar)) { while (bson_iter_next (&ar)) { if (BSON_ITER_HOLDS_DOCUMENT (&ar) && bson_iter_recurse (&ar, &citer)) { len = (int)bson_uint32_to_string (aridx++, &keyptr, key, sizeof key); bson_append_document_begin (dest, keyptr, len, &child); while (bson_iter_next (&citer)) { if (BSON_ITER_IS_KEY (&citer, "index")) { idx = bson_iter_int32 (&citer) + offset; BSON_APPEND_INT32 (&child, "index", idx); } else { value = bson_iter_value (&citer); BSON_APPEND_VALUE (&child, bson_iter_key (&citer), value); } } bson_append_document_end (dest, &child); count++; } } } RETURN (count); } void _mongoc_write_result_merge (mongoc_write_result_t *result, /* IN */ mongoc_write_command_t *command, /* IN */ const bson_t *reply, /* IN */ uint32_t offset) { int32_t server_index = 0; const bson_value_t *value; bson_iter_t iter; bson_iter_t citer; bson_iter_t ar; int32_t n_upserted = 0; int32_t affected = 0; ENTRY; BSON_ASSERT (result); BSON_ASSERT (reply); if (bson_iter_init_find (&iter, reply, "n") && BSON_ITER_HOLDS_INT32 (&iter)) { affected = bson_iter_int32 (&iter); } if (bson_iter_init_find (&iter, reply, "writeErrors") && BSON_ITER_HOLDS_ARRAY (&iter) && bson_iter_recurse (&iter, &citer) && bson_iter_next (&citer)) { result->failed = true; } switch (command->type) { case MONGOC_WRITE_COMMAND_INSERT: result->nInserted += affected; break; case MONGOC_WRITE_COMMAND_DELETE: result->nRemoved += affected; break; case MONGOC_WRITE_COMMAND_UPDATE: /* server returns each upserted _id with its index into this batch * look for "upserted": [{"index": 4, "_id": ObjectId()}, ...] */ if (bson_iter_init_find (&iter, reply, "upserted")) { if (BSON_ITER_HOLDS_ARRAY (&iter) && (bson_iter_recurse (&iter, &ar))) { while (bson_iter_next (&ar)) { if (BSON_ITER_HOLDS_DOCUMENT (&ar) && bson_iter_recurse (&ar, &citer) && bson_iter_find (&citer, "index") && BSON_ITER_HOLDS_INT32 (&citer)) { server_index = bson_iter_int32 (&citer); if (bson_iter_recurse (&ar, &citer) && bson_iter_find (&citer, "_id")) { value = bson_iter_value (&citer); _mongoc_write_result_append_upsert (result, offset + server_index, value); n_upserted++; } } } } result->nUpserted += n_upserted; /* * XXX: The following addition to nMatched needs some checking. * I'm highly skeptical of it. */ result->nMatched += BSON_MAX (0, (affected - n_upserted)); } else { result->nMatched += affected; } /* * SERVER-13001 - in a mixed sharded cluster a call to update could * return nModified (>= 2.6) or not (<= 2.4). If any call does not * return nModified we can't report a valid final count so omit the * field completely. */ if (bson_iter_init_find (&iter, reply, "nModified") && BSON_ITER_HOLDS_INT32 (&iter)) { result->nModified += bson_iter_int32 (&iter); } else { /* * nModified could be BSON_TYPE_NULL, which should also be omitted. */ result->omit_nModified = true; } break; default: BSON_ASSERT (false); break; } if (bson_iter_init_find (&iter, reply, "writeErrors") && BSON_ITER_HOLDS_ARRAY (&iter)) { _mongoc_write_result_merge_arrays (offset, result, &result->writeErrors, &iter); } if (bson_iter_init_find (&iter, reply, "writeConcernError") && BSON_ITER_HOLDS_DOCUMENT (&iter)) { uint32_t len; const uint8_t *data; bson_t write_concern_error; char str[16]; const char *key; /* writeConcernError is a subdocument in the server response * append it to the result->writeConcernErrors array */ bson_iter_document (&iter, &len, &data); bson_init_static (&write_concern_error, data, len); bson_uint32_to_string (result->n_writeConcernErrors, &key, str, sizeof str); bson_append_document (&result->writeConcernErrors, key, -1, &write_concern_error); result->n_writeConcernErrors++; } EXIT; } /* * If error is not set, set code from first document in array like * [{"code": 64, "errmsg": "duplicate"}, ...]. Format the error message * from all errors in array. */ static void _set_error_from_response (bson_t *bson_array, mongoc_error_domain_t domain, const char *error_type, bson_error_t *error /* OUT */) { bson_iter_t array_iter; bson_iter_t doc_iter; bson_string_t *compound_err; const char *errmsg = NULL; int32_t code = 0; uint32_t n_keys, i; compound_err = bson_string_new (NULL); n_keys = bson_count_keys (bson_array); if (n_keys > 1) { bson_string_append_printf (compound_err, "Multiple %s errors: ", error_type); } if (!bson_empty0 (bson_array) && bson_iter_init (&array_iter, bson_array)) { /* get first code and all error messages */ i = 0; while (bson_iter_next (&array_iter)) { if (BSON_ITER_HOLDS_DOCUMENT (&array_iter) && bson_iter_recurse (&array_iter, &doc_iter)) { /* parse doc, which is like {"code": 64, "errmsg": "duplicate"} */ while (bson_iter_next (&doc_iter)) { /* use the first error code we find */ if (BSON_ITER_IS_KEY (&doc_iter, "code") && code == 0) { code = bson_iter_int32 (&doc_iter); } else if (BSON_ITER_IS_KEY (&doc_iter, "errmsg")) { errmsg = bson_iter_utf8 (&doc_iter, NULL); /* build message like 'Multiple write errors: "foo", "bar"' */ if (n_keys > 1) { bson_string_append_printf (compound_err, "\"%s\"", errmsg); if (i < n_keys - 1) { bson_string_append (compound_err, ", "); } } else { /* single error message */ bson_string_append (compound_err, errmsg); } } } i++; } } if (code && compound_err->len) { bson_set_error (error, domain, (uint32_t) code, "%s", compound_err->str); } } bson_string_free (compound_err, true); } bool _mongoc_write_result_complete (mongoc_write_result_t *result, bson_t *bson, bson_error_t *error) { ENTRY; BSON_ASSERT (result); if (bson) { BSON_APPEND_INT32 (bson, "nInserted", result->nInserted); BSON_APPEND_INT32 (bson, "nMatched", result->nMatched); if (!result->omit_nModified) { BSON_APPEND_INT32 (bson, "nModified", result->nModified); } BSON_APPEND_INT32 (bson, "nRemoved", result->nRemoved); BSON_APPEND_INT32 (bson, "nUpserted", result->nUpserted); if (!bson_empty0 (&result->upserted)) { BSON_APPEND_ARRAY (bson, "upserted", &result->upserted); } BSON_APPEND_ARRAY (bson, "writeErrors", &result->writeErrors); if (result->n_writeConcernErrors) { BSON_APPEND_ARRAY (bson, "writeConcernErrors", &result->writeConcernErrors); } } /* set bson_error_t from first write error or write concern error */ _set_error_from_response (&result->writeErrors, MONGOC_ERROR_COMMAND, "write", &result->error); if (!result->error.code) { _set_error_from_response (&result->writeConcernErrors, MONGOC_ERROR_WRITE_CONCERN, "write concern", &result->error); } if (error) { memcpy (error, &result->error, sizeof *error); } RETURN (!result->failed && result->error.code == 0); } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-write-concern-private.h0000664000175000017500000000306012673034026025476 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_WRITE_CONCERN_PRIVATE_H #define MONGOC_WRITE_CONCERN_PRIVATE_H #if !defined (MONGOC_I_AM_A_DRIVER) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #include BSON_BEGIN_DECLS #define MONGOC_WRITE_CONCERN_FSYNC_DEFAULT -1 #define MONGOC_WRITE_CONCERN_JOURNAL_DEFAULT -1 struct _mongoc_write_concern_t { int8_t fsync_; int8_t journal; int32_t w; int32_t wtimeout; char *wtag; bool frozen; bson_t compiled; bson_t compiled_gle; }; const bson_t *_mongoc_write_concern_get_gle (mongoc_write_concern_t *write_concern); const bson_t *_mongoc_write_concern_get_bson (mongoc_write_concern_t *write_concern); bool _mongoc_write_concern_needs_gle (const mongoc_write_concern_t *write_concern); bool _mongoc_write_concern_is_valid (const mongoc_write_concern_t *write_concern); BSON_END_DECLS #endif /* MONGOC_WRITE_CONCERN_PRIVATE_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-write-concern.c0000664000175000017500000002713012673034026024025 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "mongoc-log.h" #include "mongoc-write-concern.h" #include "mongoc-write-concern-private.h" static BSON_INLINE bool _mongoc_write_concern_warn_frozen (mongoc_write_concern_t *write_concern) { if (write_concern->frozen) { MONGOC_WARNING("Cannot modify a frozen write-concern."); } return write_concern->frozen; } static void _mongoc_write_concern_freeze (mongoc_write_concern_t *write_concern); /** * mongoc_write_concern_new: * * Create a new mongoc_write_concern_t. * * Returns: A newly allocated mongoc_write_concern_t. This should be freed * with mongoc_write_concern_destroy(). */ mongoc_write_concern_t * mongoc_write_concern_new (void) { mongoc_write_concern_t *write_concern; write_concern = (mongoc_write_concern_t *)bson_malloc0(sizeof *write_concern); write_concern->w = MONGOC_WRITE_CONCERN_W_DEFAULT; write_concern->fsync_ = MONGOC_WRITE_CONCERN_FSYNC_DEFAULT; write_concern->journal = MONGOC_WRITE_CONCERN_JOURNAL_DEFAULT; return write_concern; } mongoc_write_concern_t * mongoc_write_concern_copy (const mongoc_write_concern_t *write_concern) { mongoc_write_concern_t *ret = NULL; if (write_concern) { ret = mongoc_write_concern_new(); ret->fsync_ = write_concern->fsync_; ret->journal = write_concern->journal; ret->w = write_concern->w; ret->wtimeout = write_concern->wtimeout; ret->frozen = false; ret->wtag = bson_strdup (write_concern->wtag); } return ret; } /** * mongoc_write_concern_destroy: * @write_concern: A mongoc_write_concern_t. * * Releases a mongoc_write_concern_t and all associated memory. */ void mongoc_write_concern_destroy (mongoc_write_concern_t *write_concern) { if (write_concern) { if (write_concern->compiled.len) { bson_destroy (&write_concern->compiled); bson_destroy (&write_concern->compiled_gle); } bson_free (write_concern->wtag); bson_free (write_concern); } } bool mongoc_write_concern_get_fsync (const mongoc_write_concern_t *write_concern) { BSON_ASSERT (write_concern); return (write_concern->fsync_ == true); } /** * mongoc_write_concern_set_fsync: * @write_concern: A mongoc_write_concern_t. * @fsync_: If the write concern requires fsync() by the server. * * Set if fsync() should be called on the server before acknowledging a * write request. */ void mongoc_write_concern_set_fsync (mongoc_write_concern_t *write_concern, bool fsync_) { BSON_ASSERT (write_concern); if (!_mongoc_write_concern_warn_frozen(write_concern)) { write_concern->fsync_ = !!fsync_; } } bool mongoc_write_concern_get_journal (const mongoc_write_concern_t *write_concern) { BSON_ASSERT (write_concern); return (write_concern->journal == true); } /** * mongoc_write_concern_set_journal: * @write_concern: A mongoc_write_concern_t. * @journal: If the write should be journaled. * * Set if the write request should be journaled before acknowledging the * write request. */ void mongoc_write_concern_set_journal (mongoc_write_concern_t *write_concern, bool journal) { BSON_ASSERT (write_concern); if (!_mongoc_write_concern_warn_frozen(write_concern)) { write_concern->journal = !!journal; } } int32_t mongoc_write_concern_get_w (const mongoc_write_concern_t *write_concern) { BSON_ASSERT (write_concern); return write_concern->w; } /** * mongoc_write_concern_set_w: * @w: The number of nodes for write or MONGOC_WRITE_CONCERN_W_MAJORITY * for "majority". * * Sets the number of nodes that must acknowledge the write request before * acknowledging the write request to the client. * * You may specifiy @w as MONGOC_WRITE_CONCERN_W_MAJORITY to request that * a "majority" of nodes acknowledge the request. */ void mongoc_write_concern_set_w (mongoc_write_concern_t *write_concern, int32_t w) { BSON_ASSERT (write_concern); BSON_ASSERT (w >= -3); if (!_mongoc_write_concern_warn_frozen(write_concern)) { write_concern->w = w; } } int32_t mongoc_write_concern_get_wtimeout (const mongoc_write_concern_t *write_concern) { BSON_ASSERT (write_concern); return write_concern->wtimeout; } /** * mongoc_write_concern_set_wtimeout: * @write_concern: A mongoc_write_concern_t. * @wtimeout_msec: Number of milliseconds before timeout. * * Sets the number of milliseconds to wait before considering a write * request as failed. A value of 0 indicates no write timeout. * * The @wtimeout_msec parameter must be positive or zero. Negative values will * be ignored. */ void mongoc_write_concern_set_wtimeout (mongoc_write_concern_t *write_concern, int32_t wtimeout_msec) { BSON_ASSERT (write_concern); if (wtimeout_msec < 0) { return; } if (!_mongoc_write_concern_warn_frozen(write_concern)) { write_concern->wtimeout = wtimeout_msec; } } bool mongoc_write_concern_get_wmajority (const mongoc_write_concern_t *write_concern) { BSON_ASSERT (write_concern); return (write_concern->w == MONGOC_WRITE_CONCERN_W_MAJORITY); } /** * mongoc_write_concern_set_wmajority: * @write_concern: A mongoc_write_concern_t. * @wtimeout_msec: Number of milliseconds before timeout. * * Sets the "w" of a write concern to "majority". It is suggested that * you provide a reasonable @wtimeout_msec to wait before considering the * write request failed. A @wtimeout_msec value of 0 indicates no write timeout. * * The @wtimeout_msec parameter must be positive or zero. Negative values will * be ignored. */ void mongoc_write_concern_set_wmajority (mongoc_write_concern_t *write_concern, int32_t wtimeout_msec) { BSON_ASSERT (write_concern); if (!_mongoc_write_concern_warn_frozen(write_concern)) { write_concern->w = MONGOC_WRITE_CONCERN_W_MAJORITY; if (wtimeout_msec >= 0) { write_concern->wtimeout = wtimeout_msec; } } } const char * mongoc_write_concern_get_wtag (const mongoc_write_concern_t *write_concern) { BSON_ASSERT (write_concern); if (write_concern->w == MONGOC_WRITE_CONCERN_W_TAG) { return write_concern->wtag; } return NULL; } void mongoc_write_concern_set_wtag (mongoc_write_concern_t *write_concern, const char *wtag) { BSON_ASSERT (write_concern); if (!_mongoc_write_concern_warn_frozen (write_concern)) { bson_free (write_concern->wtag); write_concern->wtag = bson_strdup (wtag); write_concern->w = MONGOC_WRITE_CONCERN_W_TAG; } } /** * mongoc_write_concern_get_bson: * @write_concern: A mongoc_write_concern_t. * * This is an internal function. * * Freeze the write concern if necessary and retrieve the encoded bson_t * representing the write concern. * * You may not modify the write concern further after calling this function. * * Returns: A bson_t that should not be modified or freed as it is owned by * the mongoc_write_concern_t instance. */ const bson_t * _mongoc_write_concern_get_bson (mongoc_write_concern_t *write_concern) { if (!write_concern->frozen) { _mongoc_write_concern_freeze(write_concern); } return &write_concern->compiled; } /** * mongoc_write_concern_get_gle: * @write_concern: A mongoc_write_concern_t. * * This is an internal function. * * Freeze the write concern if necessary and retrieve the encoded bson_t * representing the write concern as a get last error command. * * You may not modify the write concern further after calling this function. * * Returns: A bson_t that should not be modified or freed as it is owned by * the mongoc_write_concern_t instance. */ const bson_t * _mongoc_write_concern_get_gle (mongoc_write_concern_t *write_concern) { if (!write_concern->frozen) { _mongoc_write_concern_freeze(write_concern); } return &write_concern->compiled_gle; } /** * mongoc_write_concern_freeze: * @write_concern: A mongoc_write_concern_t. * * This is an internal function. * * Freeze the write concern if necessary and encode it into a bson_ts which * represent the raw bson form and the get last error command form. * * You may not modify the write concern further after calling this function. */ static void _mongoc_write_concern_freeze (mongoc_write_concern_t *write_concern) { bson_t *compiled; bson_t *compiled_gle; BSON_ASSERT (write_concern); compiled = &write_concern->compiled; compiled_gle = &write_concern->compiled_gle; write_concern->frozen = true; bson_init (compiled); bson_init (compiled_gle); if (write_concern->w == MONGOC_WRITE_CONCERN_W_TAG) { BSON_ASSERT (write_concern->wtag); BSON_APPEND_UTF8 (compiled, "w", write_concern->wtag); } else if (write_concern->w == MONGOC_WRITE_CONCERN_W_MAJORITY) { BSON_APPEND_UTF8 (compiled, "w", "majority"); } else if (write_concern->w == MONGOC_WRITE_CONCERN_W_DEFAULT) { /* Do Nothing */ } else if (write_concern->w > 0) { BSON_APPEND_INT32 (compiled, "w", write_concern->w); } if (write_concern->fsync_ != MONGOC_WRITE_CONCERN_FSYNC_DEFAULT) { bson_append_bool(compiled, "fsync", 5, !!write_concern->fsync_); } if (write_concern->journal != MONGOC_WRITE_CONCERN_JOURNAL_DEFAULT) { bson_append_bool(compiled, "j", 1, !!write_concern->journal); } if (write_concern->wtimeout) { bson_append_int32(compiled, "wtimeout", 8, write_concern->wtimeout); } BSON_APPEND_INT32 (compiled_gle, "getlasterror", 1); bson_concat (compiled_gle, compiled); } /** * mongoc_write_concern_needs_gle: * @concern: (in): A mongoc_write_concern_t. * * Checks to see if @write_concern requests that a getlasterror command is to * be delivered to the MongoDB server. * * Returns: true if a getlasterror command should be sent. */ bool _mongoc_write_concern_needs_gle (const mongoc_write_concern_t *write_concern) { if (write_concern) { return (((write_concern->w != MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED) && (write_concern->w != MONGOC_WRITE_CONCERN_W_ERRORS_IGNORED)) || mongoc_write_concern_get_fsync(write_concern) || mongoc_write_concern_get_journal(write_concern)); } return false; } /** * _mongoc_write_concern_is_valid: * @write_concern: (in): A mongoc_write_concern_t. * * Checks to see if @write_concern is valid and does not contain conflicting * options. * * Returns: true if the write concern is valid; otherwise false. */ bool _mongoc_write_concern_is_valid (const mongoc_write_concern_t *write_concern) { if (!write_concern) { return false; } /* Journal or fsync should require acknowledgement. */ if ((mongoc_write_concern_get_fsync (write_concern) || mongoc_write_concern_get_journal (write_concern)) && (write_concern->w == MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED || write_concern->w == MONGOC_WRITE_CONCERN_W_ERRORS_IGNORED)) { return false; } if (write_concern->wtimeout < 0) { return false; } return true; } mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc-write-concern.h0000664000175000017500000000642712673034026024040 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_WRITE_CONCERN_H #define MONGOC_WRITE_CONCERN_H #if !defined (MONGOC_INSIDE) && !defined (MONGOC_COMPILATION) # error "Only can be included directly." #endif #include BSON_BEGIN_DECLS #define MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED 0 #define MONGOC_WRITE_CONCERN_W_ERRORS_IGNORED -1 /* deprecated */ #define MONGOC_WRITE_CONCERN_W_DEFAULT -2 #define MONGOC_WRITE_CONCERN_W_MAJORITY -3 #define MONGOC_WRITE_CONCERN_W_TAG -4 typedef struct _mongoc_write_concern_t mongoc_write_concern_t; mongoc_write_concern_t *mongoc_write_concern_new (void); mongoc_write_concern_t *mongoc_write_concern_copy (const mongoc_write_concern_t *write_concern); void mongoc_write_concern_destroy (mongoc_write_concern_t *write_concern); bool mongoc_write_concern_get_fsync (const mongoc_write_concern_t *write_concern); void mongoc_write_concern_set_fsync (mongoc_write_concern_t *write_concern, bool fsync_); bool mongoc_write_concern_get_journal (const mongoc_write_concern_t *write_concern); void mongoc_write_concern_set_journal (mongoc_write_concern_t *write_concern, bool journal); int32_t mongoc_write_concern_get_w (const mongoc_write_concern_t *write_concern); void mongoc_write_concern_set_w (mongoc_write_concern_t *write_concern, int32_t w); const char *mongoc_write_concern_get_wtag (const mongoc_write_concern_t *write_concern); void mongoc_write_concern_set_wtag (mongoc_write_concern_t *write_concern, const char *tag); int32_t mongoc_write_concern_get_wtimeout (const mongoc_write_concern_t *write_concern); void mongoc_write_concern_set_wtimeout (mongoc_write_concern_t *write_concern, int32_t wtimeout_msec); bool mongoc_write_concern_get_wmajority (const mongoc_write_concern_t *write_concern); void mongoc_write_concern_set_wmajority (mongoc_write_concern_t *write_concern, int32_t wtimeout_msec); BSON_END_DECLS #endif /* MONGOC_WRITE_CONCERN_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/mongoc.h0000664000175000017500000000324212673034026021253 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_H #define MONGOC_H #include #define MONGOC_INSIDE #include "mongoc-bulk-operation.h" #include "mongoc-client.h" #include "mongoc-client-pool.h" #include "mongoc-collection.h" #include "mongoc-config.h" #include "mongoc-cursor.h" #include "mongoc-database.h" #include "mongoc-index.h" #include "mongoc-error.h" #include "mongoc-flags.h" #include "mongoc-gridfs.h" #include "mongoc-gridfs-file.h" #include "mongoc-gridfs-file-list.h" #include "mongoc-gridfs-file-page.h" #include "mongoc-host-list.h" #include "mongoc-init.h" #include "mongoc-matcher.h" #include "mongoc-opcode.h" #include "mongoc-log.h" #include "mongoc-socket.h" #include "mongoc-stream.h" #include "mongoc-stream-buffered.h" #include "mongoc-stream-file.h" #include "mongoc-stream-gridfs.h" #include "mongoc-stream-socket.h" #include "mongoc-uri.h" #include "mongoc-write-concern.h" #include "mongoc-version.h" #include "mongoc-version-functions.h" #ifdef MONGOC_ENABLE_SSL #include "mongoc-rand.h" #include "mongoc-stream-tls.h" #include "mongoc-ssl.h" #endif #undef MONGOC_INSIDE #endif /* MONGOC_H */ mongodb-1.1.5/src/libmongoc/src/mongoc/op-delete.def0000664000175000017500000000031612673034026022155 0ustar jmikolajmikolaRPC( delete, INT32_FIELD(msg_len) INT32_FIELD(request_id) INT32_FIELD(response_to) INT32_FIELD(opcode) INT32_FIELD(zero) CSTRING_FIELD(collection) ENUM_FIELD(flags) BSON_FIELD(selector) ) mongodb-1.1.5/src/libmongoc/src/mongoc/op-get-more.def0000664000175000017500000000032612673034026022433 0ustar jmikolajmikolaRPC( get_more, INT32_FIELD(msg_len) INT32_FIELD(request_id) INT32_FIELD(response_to) INT32_FIELD(opcode) INT32_FIELD(zero) CSTRING_FIELD(collection) INT32_FIELD(n_return) INT64_FIELD(cursor_id) ) mongodb-1.1.5/src/libmongoc/src/mongoc/op-header.def0000664000175000017500000000016312673034026022143 0ustar jmikolajmikolaRPC( header, INT32_FIELD(msg_len) INT32_FIELD(request_id) INT32_FIELD(response_to) INT32_FIELD(opcode) ) mongodb-1.1.5/src/libmongoc/src/mongoc/op-insert.def0000664000175000017500000000030212673034026022212 0ustar jmikolajmikolaRPC( insert, INT32_FIELD(msg_len) INT32_FIELD(request_id) INT32_FIELD(response_to) INT32_FIELD(opcode) ENUM_FIELD(flags) CSTRING_FIELD(collection) IOVEC_ARRAY_FIELD(documents) ) mongodb-1.1.5/src/libmongoc/src/mongoc/op-kill-cursors.def0000664000175000017500000000026512673034026023347 0ustar jmikolajmikolaRPC( kill_cursors, INT32_FIELD(msg_len) INT32_FIELD(request_id) INT32_FIELD(response_to) INT32_FIELD(opcode) INT32_FIELD(zero) INT64_ARRAY_FIELD(n_cursors, cursors) ) mongodb-1.1.5/src/libmongoc/src/mongoc/op-msg.def0000664000175000017500000000020512673034026021476 0ustar jmikolajmikolaRPC( msg, INT32_FIELD(msg_len) INT32_FIELD(request_id) INT32_FIELD(response_to) INT32_FIELD(opcode) CSTRING_FIELD(msg) ) mongodb-1.1.5/src/libmongoc/src/mongoc/op-query.def0000664000175000017500000000041612673034026022061 0ustar jmikolajmikolaRPC( query, INT32_FIELD(msg_len) INT32_FIELD(request_id) INT32_FIELD(response_to) INT32_FIELD(opcode) ENUM_FIELD(flags) CSTRING_FIELD(collection) INT32_FIELD(skip) INT32_FIELD(n_return) BSON_FIELD(query) BSON_OPTIONAL(fields, BSON_FIELD(fields)) ) mongodb-1.1.5/src/libmongoc/src/mongoc/op-reply.def0000664000175000017500000000036112673034026022046 0ustar jmikolajmikolaRPC( reply, INT32_FIELD(msg_len) INT32_FIELD(request_id) INT32_FIELD(response_to) INT32_FIELD(opcode) ENUM_FIELD(flags) INT64_FIELD(cursor_id) INT32_FIELD(start_from) INT32_FIELD(n_returned) BSON_ARRAY_FIELD(documents) ) mongodb-1.1.5/src/libmongoc/src/mongoc/op-update.def0000664000175000017500000000034312673034026022175 0ustar jmikolajmikolaRPC( update, INT32_FIELD(msg_len) INT32_FIELD(request_id) INT32_FIELD(response_to) INT32_FIELD(opcode) INT32_FIELD(zero) CSTRING_FIELD(collection) ENUM_FIELD(flags) BSON_FIELD(selector) BSON_FIELD(update) ) mongodb-1.1.5/src/libmongoc/src/mongoc/utlist.h0000664000175000017500000015511212673034026021321 0ustar jmikolajmikola/* Copyright (c) 2007-2014, Troy D. Hanson http://troydhanson.github.com/uthash/ All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef UTLIST_H #define UTLIST_H #define UTLIST_VERSION 1.9.9 #include /* * This file contains macros to manipulate singly and doubly-linked lists. * * 1. LL_ macros: singly-linked lists. * 2. DL_ macros: doubly-linked lists. * 3. CDL_ macros: circular doubly-linked lists. * * To use singly-linked lists, your structure must have a "next" pointer. * To use doubly-linked lists, your structure must "prev" and "next" pointers. * Either way, the pointer to the head of the list must be initialized to NULL. * * ----------------.EXAMPLE ------------------------- * struct item { * int id; * struct item *prev, *next; * } * * struct item *list = NULL: * * int main() { * struct item *item; * ... allocate and populate item ... * DL_APPEND(list, item); * } * -------------------------------------------------- * * For doubly-linked lists, the append and delete macros are O(1) * For singly-linked lists, append and delete are O(n) but prepend is O(1) * The sort macro is O(n log(n)) for all types of single/double/circular lists. */ /* These macros use decltype or the earlier __typeof GNU extension. As decltype is only available in newer compilers (VS2010 or gcc 4.3+ when compiling c++ code), this code uses whatever method is needed or, for VS2008 where neither is available, uses casting workarounds. */ #ifdef _MSC_VER /* MS compiler */ #if _MSC_VER >= 1600 && defined(__cplusplus) /* VS2010 or newer in C++ mode */ #define LDECLTYPE(x) decltype(x) #else /* VS2008 or older (or VS2010 in C mode) */ #define NO_DECLTYPE #define LDECLTYPE(x) char* #endif #elif defined(__ICCARM__) #define NO_DECLTYPE #define LDECLTYPE(x) char* #else /* GNU, Sun and other compilers */ #define LDECLTYPE(x) __typeof(x) #endif /* for VS2008 we use some workarounds to get around the lack of decltype, * namely, we always reassign our tmp variable to the list head if we need * to dereference its prev/next pointers, and save/restore the real head.*/ #ifdef NO_DECLTYPE #define _SV(elt,list) _tmp = (char*)(list); {char **_alias = (char**)&(list); *_alias = (elt); } #define _NEXT(elt,list,next) ((char*)((list)->next)) #define _NEXTASGN(elt,list,to,next) { char **_alias = (char**)&((list)->next); *_alias=(char*)(to); } /* #define _PREV(elt,list,prev) ((char*)((list)->prev)) */ #define _PREVASGN(elt,list,to,prev) { char **_alias = (char**)&((list)->prev); *_alias=(char*)(to); } #define _RS(list) { char **_alias = (char**)&(list); *_alias=_tmp; } #define _CASTASGN(a,b) { char **_alias = (char**)&(a); *_alias=(char*)(b); } #else #define _SV(elt,list) #define _NEXT(elt,list,next) ((elt)->next) #define _NEXTASGN(elt,list,to,next) ((elt)->next)=(to) /* #define _PREV(elt,list,prev) ((elt)->prev) */ #define _PREVASGN(elt,list,to,prev) ((elt)->prev)=(to) #define _RS(list) #define _CASTASGN(a,b) (a)=(b) #endif /****************************************************************************** * The sort macro is an adaptation of Simon Tatham's O(n log(n)) mergesort * * Unwieldy variable names used here to avoid shadowing passed-in variables. * *****************************************************************************/ #define LL_SORT(list, cmp) \ LL_SORT2(list, cmp, next) #define LL_SORT2(list, cmp, next) \ do { \ LDECLTYPE(list) _ls_p; \ LDECLTYPE(list) _ls_q; \ LDECLTYPE(list) _ls_e; \ LDECLTYPE(list) _ls_tail; \ int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ if (list) { \ _ls_insize = 1; \ _ls_looping = 1; \ while (_ls_looping) { \ _CASTASGN(_ls_p,list); \ list = NULL; \ _ls_tail = NULL; \ _ls_nmerges = 0; \ while (_ls_p) { \ _ls_nmerges++; \ _ls_q = _ls_p; \ _ls_psize = 0; \ for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ _ls_psize++; \ _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list,next); _RS(list); \ if (!_ls_q) break; \ } \ _ls_qsize = _ls_insize; \ while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \ if (_ls_psize == 0) { \ _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \ _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \ } else if (_ls_qsize == 0 || !_ls_q) { \ _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \ _NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \ } else if (cmp(_ls_p,_ls_q) <= 0) { \ _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \ _NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \ } else { \ _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \ _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \ } \ if (_ls_tail) { \ _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e,next); _RS(list); \ } else { \ _CASTASGN(list,_ls_e); \ } \ _ls_tail = _ls_e; \ } \ _ls_p = _ls_q; \ } \ if (_ls_tail) { \ _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,NULL,next); _RS(list); \ } \ if (_ls_nmerges <= 1) { \ _ls_looping=0; \ } \ _ls_insize *= 2; \ } \ } \ } while (0) #define DL_SORT(list, cmp) \ DL_SORT2(list, cmp, prev, next) #define DL_SORT2(list, cmp, prev, next) \ do { \ LDECLTYPE(list) _ls_p; \ LDECLTYPE(list) _ls_q; \ LDECLTYPE(list) _ls_e; \ LDECLTYPE(list) _ls_tail; \ int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ if (list) { \ _ls_insize = 1; \ _ls_looping = 1; \ while (_ls_looping) { \ _CASTASGN(_ls_p,list); \ list = NULL; \ _ls_tail = NULL; \ _ls_nmerges = 0; \ while (_ls_p) { \ _ls_nmerges++; \ _ls_q = _ls_p; \ _ls_psize = 0; \ for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ _ls_psize++; \ _SV(_ls_q,list); _ls_q = _NEXT(_ls_q,list,next); _RS(list); \ if (!_ls_q) break; \ } \ _ls_qsize = _ls_insize; \ while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \ if (_ls_psize == 0) { \ _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \ _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \ } else if (_ls_qsize == 0 || !_ls_q) { \ _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \ _NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \ } else if (cmp(_ls_p,_ls_q) <= 0) { \ _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \ _NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \ } else { \ _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \ _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \ } \ if (_ls_tail) { \ _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e,next); _RS(list); \ } else { \ _CASTASGN(list,_ls_e); \ } \ _SV(_ls_e,list); _PREVASGN(_ls_e,list,_ls_tail,prev); _RS(list); \ _ls_tail = _ls_e; \ } \ _ls_p = _ls_q; \ } \ _CASTASGN(list->prev, _ls_tail); \ _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,NULL,next); _RS(list); \ if (_ls_nmerges <= 1) { \ _ls_looping=0; \ } \ _ls_insize *= 2; \ } \ } \ } while (0) #define CDL_SORT(list, cmp) \ CDL_SORT2(list, cmp, prev, next) #define CDL_SORT2(list, cmp, prev, next) \ do { \ LDECLTYPE(list) _ls_p; \ LDECLTYPE(list) _ls_q; \ LDECLTYPE(list) _ls_e; \ LDECLTYPE(list) _ls_tail; \ LDECLTYPE(list) _ls_oldhead; \ LDECLTYPE(list) _tmp; \ int _ls_insize, _ls_nmerges, _ls_psize, _ls_qsize, _ls_i, _ls_looping; \ if (list) { \ _ls_insize = 1; \ _ls_looping = 1; \ while (_ls_looping) { \ _CASTASGN(_ls_p,list); \ _CASTASGN(_ls_oldhead,list); \ list = NULL; \ _ls_tail = NULL; \ _ls_nmerges = 0; \ while (_ls_p) { \ _ls_nmerges++; \ _ls_q = _ls_p; \ _ls_psize = 0; \ for (_ls_i = 0; _ls_i < _ls_insize; _ls_i++) { \ _ls_psize++; \ _SV(_ls_q,list); \ if (_NEXT(_ls_q,list,next) == _ls_oldhead) { \ _ls_q = NULL; \ } else { \ _ls_q = _NEXT(_ls_q,list,next); \ } \ _RS(list); \ if (!_ls_q) break; \ } \ _ls_qsize = _ls_insize; \ while (_ls_psize > 0 || (_ls_qsize > 0 && _ls_q)) { \ if (_ls_psize == 0) { \ _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \ _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \ if (_ls_q == _ls_oldhead) { _ls_q = NULL; } \ } else if (_ls_qsize == 0 || !_ls_q) { \ _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \ _NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \ if (_ls_p == _ls_oldhead) { _ls_p = NULL; } \ } else if (cmp(_ls_p,_ls_q) <= 0) { \ _ls_e = _ls_p; _SV(_ls_p,list); _ls_p = \ _NEXT(_ls_p,list,next); _RS(list); _ls_psize--; \ if (_ls_p == _ls_oldhead) { _ls_p = NULL; } \ } else { \ _ls_e = _ls_q; _SV(_ls_q,list); _ls_q = \ _NEXT(_ls_q,list,next); _RS(list); _ls_qsize--; \ if (_ls_q == _ls_oldhead) { _ls_q = NULL; } \ } \ if (_ls_tail) { \ _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_ls_e,next); _RS(list); \ } else { \ _CASTASGN(list,_ls_e); \ } \ _SV(_ls_e,list); _PREVASGN(_ls_e,list,_ls_tail,prev); _RS(list); \ _ls_tail = _ls_e; \ } \ _ls_p = _ls_q; \ } \ _CASTASGN(list->prev,_ls_tail); \ _CASTASGN(_tmp,list); \ _SV(_ls_tail,list); _NEXTASGN(_ls_tail,list,_tmp,next); _RS(list); \ if (_ls_nmerges <= 1) { \ _ls_looping=0; \ } \ _ls_insize *= 2; \ } \ } \ } while (0) /****************************************************************************** * singly linked list macros (non-circular) * *****************************************************************************/ #define LL_PREPEND(head,add) \ LL_PREPEND2(head,add,next) #define LL_PREPEND2(head,add,next) \ do { \ (add)->next = head; \ head = add; \ } while (0) #define LL_CONCAT(head1,head2) \ LL_CONCAT2(head1,head2,next) #define LL_CONCAT2(head1,head2,next) \ do { \ LDECLTYPE(head1) _tmp; \ if (head1) { \ _tmp = head1; \ while (_tmp->next) { _tmp = _tmp->next; } \ _tmp->next=(head2); \ } else { \ (head1)=(head2); \ } \ } while (0) #define LL_APPEND(head,add) \ LL_APPEND2(head,add,next) #define LL_APPEND2(head,add,next) \ do { \ LDECLTYPE(head) _tmp; \ (add)->next=NULL; \ if (head) { \ _tmp = head; \ while (_tmp->next) { _tmp = _tmp->next; } \ _tmp->next=(add); \ } else { \ (head)=(add); \ } \ } while (0) #define LL_DELETE(head,del) \ LL_DELETE2(head,del,next) #define LL_DELETE2(head,del,next) \ do { \ LDECLTYPE(head) _tmp; \ if ((head) == (del)) { \ (head)=(head)->next; \ } else { \ _tmp = head; \ while (_tmp->next && (_tmp->next != (del))) { \ _tmp = _tmp->next; \ } \ if (_tmp->next) { \ _tmp->next = ((del)->next); \ } \ } \ } while (0) /* Here are VS2008 replacements for LL_APPEND and LL_DELETE */ #define LL_APPEND_VS2008(head,add) \ LL_APPEND2_VS2008(head,add,next) #define LL_APPEND2_VS2008(head,add,next) \ do { \ if (head) { \ (add)->next = head; /* use add->next as a temp variable */ \ while ((add)->next->next) { (add)->next = (add)->next->next; } \ (add)->next->next=(add); \ } else { \ (head)=(add); \ } \ (add)->next=NULL; \ } while (0) #define LL_DELETE_VS2008(head,del) \ LL_DELETE2_VS2008(head,del,next) #define LL_DELETE2_VS2008(head,del,next) \ do { \ if ((head) == (del)) { \ (head)=(head)->next; \ } else { \ char *_tmp = (char*)(head); \ while ((head)->next && ((head)->next != (del))) { \ head = (head)->next; \ } \ if ((head)->next) { \ (head)->next = ((del)->next); \ } \ { \ char **_head_alias = (char**)&(head); \ *_head_alias = _tmp; \ } \ } \ } while (0) #ifdef NO_DECLTYPE #undef LL_APPEND #define LL_APPEND LL_APPEND_VS2008 #undef LL_DELETE #define LL_DELETE LL_DELETE_VS2008 #undef LL_DELETE2 #define LL_DELETE2 LL_DELETE2_VS2008 #undef LL_APPEND2 #define LL_APPEND2 LL_APPEND2_VS2008 #undef LL_CONCAT /* no LL_CONCAT_VS2008 */ #undef DL_CONCAT /* no DL_CONCAT_VS2008 */ #endif /* end VS2008 replacements */ #define LL_COUNT(head,el,counter) \ LL_COUNT2(head,el,counter,next) \ #define LL_COUNT2(head,el,counter,next) \ { \ counter = 0; \ LL_FOREACH2(head,el,next){ ++counter; } \ } #define LL_FOREACH(head,el) \ LL_FOREACH2(head,el,next) #define LL_FOREACH2(head,el,next) \ for(el=head;el;el=(el)->next) #define LL_FOREACH_SAFE(head,el,tmp) \ LL_FOREACH_SAFE2(head,el,tmp,next) #define LL_FOREACH_SAFE2(head,el,tmp,next) \ for((el)=(head);(el) && (tmp = (el)->next, 1); (el) = tmp) #define LL_SEARCH_SCALAR(head,out,field,val) \ LL_SEARCH_SCALAR2(head,out,field,val,next) #define LL_SEARCH_SCALAR2(head,out,field,val,next) \ do { \ LL_FOREACH2(head,out,next) { \ if ((out)->field == (val)) break; \ } \ } while(0) #define LL_SEARCH(head,out,elt,cmp) \ LL_SEARCH2(head,out,elt,cmp,next) #define LL_SEARCH2(head,out,elt,cmp,next) \ do { \ LL_FOREACH2(head,out,next) { \ if ((cmp(out,elt))==0) break; \ } \ } while(0) #define LL_REPLACE_ELEM(head, el, add) \ do { \ LDECLTYPE(head) _tmp; \ assert(head != NULL); \ assert(el != NULL); \ assert(add != NULL); \ (add)->next = (el)->next; \ if ((head) == (el)) { \ (head) = (add); \ } else { \ _tmp = head; \ while (_tmp->next && (_tmp->next != (el))) { \ _tmp = _tmp->next; \ } \ if (_tmp->next) { \ _tmp->next = (add); \ } \ } \ } while (0) #define LL_PREPEND_ELEM(head, el, add) \ do { \ LDECLTYPE(head) _tmp; \ assert(head != NULL); \ assert(el != NULL); \ assert(add != NULL); \ (add)->next = (el); \ if ((head) == (el)) { \ (head) = (add); \ } else { \ _tmp = head; \ while (_tmp->next && (_tmp->next != (el))) { \ _tmp = _tmp->next; \ } \ if (_tmp->next) { \ _tmp->next = (add); \ } \ } \ } while (0) \ /****************************************************************************** * doubly linked list macros (non-circular) * *****************************************************************************/ #define DL_PREPEND(head,add) \ DL_PREPEND2(head,add,prev,next) #define DL_PREPEND2(head,add,prev,next) \ do { \ (add)->next = head; \ if (head) { \ (add)->prev = (head)->prev; \ (head)->prev = (add); \ } else { \ (add)->prev = (add); \ } \ (head) = (add); \ } while (0) #define DL_APPEND(head,add) \ DL_APPEND2(head,add,prev,next) #define DL_APPEND2(head,add,prev,next) \ do { \ if (head) { \ (add)->prev = (head)->prev; \ (head)->prev->next = (add); \ (head)->prev = (add); \ (add)->next = NULL; \ } else { \ (head)=(add); \ (head)->prev = (head); \ (head)->next = NULL; \ } \ } while (0) #define DL_CONCAT(head1,head2) \ DL_CONCAT2(head1,head2,prev,next) #define DL_CONCAT2(head1,head2,prev,next) \ do { \ LDECLTYPE(head1) _tmp; \ if (head2) { \ if (head1) { \ _tmp = (head2)->prev; \ (head2)->prev = (head1)->prev; \ (head1)->prev->next = (head2); \ (head1)->prev = _tmp; \ } else { \ (head1)=(head2); \ } \ } \ } while (0) #define DL_DELETE(head,del) \ DL_DELETE2(head,del,prev,next) #define DL_DELETE2(head,del,prev,next) \ do { \ assert((del)->prev != NULL); \ if ((del)->prev == (del)) { \ (head)=NULL; \ } else if ((del)==(head)) { \ (del)->next->prev = (del)->prev; \ (head) = (del)->next; \ } else { \ (del)->prev->next = (del)->next; \ if ((del)->next) { \ (del)->next->prev = (del)->prev; \ } else { \ (head)->prev = (del)->prev; \ } \ } \ } while (0) #define DL_COUNT(head,el,counter) \ DL_COUNT2(head,el,counter,next) \ #define DL_COUNT2(head,el,counter,next) \ { \ counter = 0; \ DL_FOREACH2(head,el,next){ ++counter; } \ } #define DL_FOREACH(head,el) \ DL_FOREACH2(head,el,next) #define DL_FOREACH2(head,el,next) \ for(el=head;el;el=(el)->next) /* this version is safe for deleting the elements during iteration */ #define DL_FOREACH_SAFE(head,el,tmp) \ DL_FOREACH_SAFE2(head,el,tmp,next) #define DL_FOREACH_SAFE2(head,el,tmp,next) \ for((el)=(head);(el) && (tmp = (el)->next, 1); (el) = tmp) /* these are identical to their singly-linked list counterparts */ #define DL_SEARCH_SCALAR LL_SEARCH_SCALAR #define DL_SEARCH LL_SEARCH #define DL_SEARCH_SCALAR2 LL_SEARCH_SCALAR2 #define DL_SEARCH2 LL_SEARCH2 #define DL_REPLACE_ELEM(head, el, add) \ do { \ assert(head != NULL); \ assert(el != NULL); \ assert(add != NULL); \ if ((head) == (el)) { \ (head) = (add); \ (add)->next = (el)->next; \ if ((el)->next == NULL) { \ (add)->prev = (add); \ } else { \ (add)->prev = (el)->prev; \ (add)->next->prev = (add); \ } \ } else { \ (add)->next = (el)->next; \ (add)->prev = (el)->prev; \ (add)->prev->next = (add); \ if ((el)->next == NULL) { \ (head)->prev = (add); \ } else { \ (add)->next->prev = (add); \ } \ } \ } while (0) #define DL_PREPEND_ELEM(head, el, add) \ do { \ assert(head != NULL); \ assert(el != NULL); \ assert(add != NULL); \ (add)->next = (el); \ (add)->prev = (el)->prev; \ (el)->prev = (add); \ if ((head) == (el)) { \ (head) = (add); \ } else { \ (add)->prev->next = (add); \ } \ } while (0) \ /****************************************************************************** * circular doubly linked list macros * *****************************************************************************/ #define CDL_PREPEND(head,add) \ CDL_PREPEND2(head,add,prev,next) #define CDL_PREPEND2(head,add,prev,next) \ do { \ if (head) { \ (add)->prev = (head)->prev; \ (add)->next = (head); \ (head)->prev = (add); \ (add)->prev->next = (add); \ } else { \ (add)->prev = (add); \ (add)->next = (add); \ } \ (head)=(add); \ } while (0) #define CDL_DELETE(head,del) \ CDL_DELETE2(head,del,prev,next) #define CDL_DELETE2(head,del,prev,next) \ do { \ if ( ((head)==(del)) && ((head)->next == (head))) { \ (head) = 0L; \ } else { \ (del)->next->prev = (del)->prev; \ (del)->prev->next = (del)->next; \ if ((del) == (head)) (head)=(del)->next; \ } \ } while (0) #define CDL_COUNT(head,el,counter) \ CDL_COUNT2(head,el,counter,next) \ #define CDL_COUNT2(head, el, counter,next) \ { \ counter = 0; \ CDL_FOREACH2(head,el,next){ ++counter; } \ } #define CDL_FOREACH(head,el) \ CDL_FOREACH2(head,el,next) #define CDL_FOREACH2(head,el,next) \ for(el=head;el;el=((el)->next==head ? 0L : (el)->next)) #define CDL_FOREACH_SAFE(head,el,tmp1,tmp2) \ CDL_FOREACH_SAFE2(head,el,tmp1,tmp2,prev,next) #define CDL_FOREACH_SAFE2(head,el,tmp1,tmp2,prev,next) \ for((el)=(head), ((tmp1)=(head)?((head)->prev):NULL); \ (el) && ((tmp2)=(el)->next, 1); \ ((el) = (((el)==(tmp1)) ? 0L : (tmp2)))) #define CDL_SEARCH_SCALAR(head,out,field,val) \ CDL_SEARCH_SCALAR2(head,out,field,val,next) #define CDL_SEARCH_SCALAR2(head,out,field,val,next) \ do { \ CDL_FOREACH2(head,out,next) { \ if ((out)->field == (val)) break; \ } \ } while(0) #define CDL_SEARCH(head,out,elt,cmp) \ CDL_SEARCH2(head,out,elt,cmp,next) #define CDL_SEARCH2(head,out,elt,cmp,next) \ do { \ CDL_FOREACH2(head,out,next) { \ if ((cmp(out,elt))==0) break; \ } \ } while(0) #define CDL_REPLACE_ELEM(head, el, add) \ do { \ assert(head != NULL); \ assert(el != NULL); \ assert(add != NULL); \ if ((el)->next == (el)) { \ (add)->next = (add); \ (add)->prev = (add); \ (head) = (add); \ } else { \ (add)->next = (el)->next; \ (add)->prev = (el)->prev; \ (add)->next->prev = (add); \ (add)->prev->next = (add); \ if ((head) == (el)) { \ (head) = (add); \ } \ } \ } while (0) #define CDL_PREPEND_ELEM(head, el, add) \ do { \ assert(head != NULL); \ assert(el != NULL); \ assert(add != NULL); \ (add)->next = (el); \ (add)->prev = (el)->prev; \ (el)->prev = (add); \ (add)->prev->next = (add); \ if ((head) == (el)) { \ (head) = (add); \ } \ } while (0) \ #endif /* UTLIST_H */ mongodb-1.1.5/src/libmongoc/VERSION_CURRENT0000664000175000017500000000000512673034026020013 0ustar jmikolajmikola1.3.3mongodb-1.1.5/src/libmongoc/VERSION_RELEASED0000664000175000017500000000000512673034026020055 0ustar jmikolajmikola1.3.3mongodb-1.1.5/src/bson.c0000664000175000017500000014115112673034026014705 0ustar jmikolajmikola/* +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ | Copyright (c) 2014-2015 Hannes Magnusson | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Hannes Magnusson | +----------------------------------------------------------------------+ */ /* $Id$ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif /* External libs */ #include /* PHP Core stuff */ #include #include #include #include /* PHP array helpers */ #include "php_array_api.h" /* Our Compatability header */ #include "phongo_compat.h" /* Our stuffz */ #include "php_phongo.h" #include "php_bson.h" #if SIZEOF_PHONGO_LONG == 8 # define BSON_APPEND_INT(b, key, keylen, val) \ if (val > INT32_MAX || val < INT32_MIN) { \ bson_append_int64(b, key, keylen, val); \ } else { \ bson_append_int32(b, key, keylen, val); \ } #elif SIZEOF_PHONGO_LONG == 4 # define BSON_APPEND_INT(b, key, keylen, val) \ bson_append_int32(b, key, keylen, val) #else # error Unsupported architecture (integers are neither 32-bit nor 64-bit) #endif #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "PHONGO-BSON" #define PHONGO_ODM_FIELD_NAME "__pclass" #define PHONGO_IS_CLASS_INSTANTIATABLE(ce) \ (!(ce->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS))) PHP_MINIT_FUNCTION(bson) { (void)type; /* We don't care if we are loaded via dl() or extension= */ (void)module_number; /* Really doesn't matter which module number we are */ /* Register BSONable */ return SUCCESS; } /* Forward declarations */ bool php_phongo_bson_visit_document(const bson_iter_t *iter ARG_UNUSED, const char *key, const bson_t *v_document, void *data); bool php_phongo_bson_visit_array(const bson_iter_t *iter ARG_UNUSED, const char *key, const bson_t *v_document, void *data); /* {{{ Santa's Little Helper: Object getters */ void php_phongo_objectid_get_id(zval *object, bson_oid_t *oid TSRMLS_DC) { php_phongo_objectid_t *intern; intern = Z_OBJECTID_OBJ_P(object); bson_oid_init_from_string(oid, intern->oid); } int64_t php_phongo_utcdatetime_get_milliseconds(zval *object TSRMLS_DC) { php_phongo_utcdatetime_t *intern; intern = Z_UTCDATETIME_OBJ_P(object); return intern->milliseconds; } uint32_t php_phongo_timestamp_get_increment(zval *object TSRMLS_DC) { php_phongo_timestamp_t *intern; intern = Z_TIMESTAMP_OBJ_P(object); return intern->increment; } uint32_t php_phongo_timestamp_get_timestamp(zval *object TSRMLS_DC) { php_phongo_timestamp_t *intern; intern = Z_TIMESTAMP_OBJ_P(object); return intern->timestamp; } bool php_phongo_javascript_has_scope(zval *object TSRMLS_DC) { php_phongo_javascript_t *intern; intern = Z_JAVASCRIPT_OBJ_P(object); return !!intern->document; } char *php_phongo_javascript_get_javascript(zval *object TSRMLS_DC) { php_phongo_javascript_t *intern; intern = Z_JAVASCRIPT_OBJ_P(object); return intern->javascript; } bson_t *php_phongo_javascript_get_scope(zval *object TSRMLS_DC) { php_phongo_javascript_t *intern; intern = Z_JAVASCRIPT_OBJ_P(object); return intern->document; } int php_phongo_binary_get_data(zval *object, char **data TSRMLS_DC) { php_phongo_binary_t *intern; intern = Z_BINARY_OBJ_P(object); *data = intern->data; return intern->data_len; } uint8_t php_phongo_binary_get_type(zval *object TSRMLS_DC) { php_phongo_binary_t *intern; intern = Z_BINARY_OBJ_P(object); return intern->type; } char *php_phongo_regex_get_pattern(zval *object TSRMLS_DC) { php_phongo_regex_t *intern; intern = Z_REGEX_OBJ_P(object); return intern->pattern; } char *php_phongo_regex_get_flags(zval *object TSRMLS_DC) { php_phongo_regex_t *intern; intern = Z_REGEX_OBJ_P(object); return intern->flags; } /* }}} */ #if 0 bool php_phongo_bson_visit_before(const bson_iter_t *iter ARG_UNUSED, const char *key, void *data) /* {{{ */ { return false; } /* }}} */ bool php_phongo_bson_visit_after(const bson_iter_t *iter ARG_UNUSED, const char *key, void *data) /* {{{ */ { return false; } /* }}} */ #endif void php_phongo_bson_visit_corrupt(const bson_iter_t *iter ARG_UNUSED, void *data ARG_UNUSED) /* {{{ */ { mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "Corrupt BSON data detected!"); } /* }}} */ bool php_phongo_bson_visit_double(const bson_iter_t *iter ARG_UNUSED, const char *key, double v_double, void *data) /* {{{ */ { #if PHP_VERSION_ID >= 70000 zval *retval = &((php_phongo_bson_state *)data)->zchild; #else zval *retval = ((php_phongo_bson_state *)data)->zchild; #endif add_assoc_double(retval, key, v_double); return false; } /* }}} */ bool php_phongo_bson_visit_utf8(const bson_iter_t *iter ARG_UNUSED, const char *key, size_t v_utf8_len, const char *v_utf8, void *data) /* {{{ */ { #if PHP_VERSION_ID >= 70000 zval *retval = &((php_phongo_bson_state *)data)->zchild; #else zval *retval = ((php_phongo_bson_state *)data)->zchild; #endif ADD_ASSOC_STRING_EX(retval, key, strlen(key), (char *)v_utf8, v_utf8_len); return false; } /* }}} */ bool php_phongo_bson_visit_binary(const bson_iter_t *iter ARG_UNUSED, const char *key, bson_subtype_t v_subtype, size_t v_binary_len, const uint8_t *v_binary, void *data) /* {{{ */ { #if PHP_VERSION_ID >= 70000 zval *retval = &((php_phongo_bson_state *)data)->zchild; #else zval *retval = ((php_phongo_bson_state *)data)->zchild; #endif TSRMLS_FETCH(); if (v_subtype == 0x80 && strcmp(key, PHONGO_ODM_FIELD_NAME) == 0) { #if PHP_VERSION_ID >= 70000 zend_string *zs_classname = zend_string_init((const char *)v_binary, v_binary_len, 0); zend_class_entry *found_ce = zend_fetch_class(zs_classname, ZEND_FETCH_CLASS_AUTO|ZEND_FETCH_CLASS_SILENT TSRMLS_CC); zend_string_free(zs_classname); #else zend_class_entry *found_ce = zend_fetch_class((char *)v_binary, v_binary_len, ZEND_FETCH_CLASS_AUTO|ZEND_FETCH_CLASS_SILENT TSRMLS_CC); #endif if (found_ce && PHONGO_IS_CLASS_INSTANTIATABLE(found_ce) && instanceof_function(found_ce, php_phongo_persistable_ce TSRMLS_CC)) { ((php_phongo_bson_state *)data)->odm = found_ce; } } { #if PHP_VERSION_ID >= 70000 zval zchild; php_phongo_new_binary_from_binary_and_type(&zchild, (const char *)v_binary, v_binary_len, v_subtype TSRMLS_CC); ADD_ASSOC_ZVAL(retval, key, &zchild); Z_SET_REFCOUNT(zchild, 1); #else zval *zchild = NULL; MAKE_STD_ZVAL(zchild); php_phongo_new_binary_from_binary_and_type(zchild, (const char *)v_binary, v_binary_len, v_subtype TSRMLS_CC); ADD_ASSOC_ZVAL(retval, key, zchild); Z_SET_REFCOUNT_P(zchild, 1); #endif } return false; } /* }}} */ #if 0 bool php_phongo_bson_visit_undefined(const bson_iter_t *iter ARG_UNUSED, const char *key, void *data) /* {{{ */ { printf("Not Implemented\n"); return true; } /* }}} */ #endif bool php_phongo_bson_visit_oid(const bson_iter_t *iter ARG_UNUSED, const char *key, const bson_oid_t *v_oid, void *data) /* {{{ */ { #if PHP_VERSION_ID >= 70000 zval *retval = &((php_phongo_bson_state *)data)->zchild; #else zval *retval = ((php_phongo_bson_state *)data)->zchild; #endif #if PHP_VERSION_ID >= 70000 zval zchild; php_phongo_objectid_new_from_oid(&zchild, v_oid TSRMLS_CC); ADD_ASSOC_ZVAL(retval, key, &zchild); #else zval *zchild = NULL; TSRMLS_FETCH(); MAKE_STD_ZVAL(zchild); php_phongo_objectid_new_from_oid(zchild, v_oid TSRMLS_CC); ADD_ASSOC_ZVAL(retval, key, zchild); Z_SET_REFCOUNT_P(zchild, 1); #endif return false; } /* }}} */ bool php_phongo_bson_visit_bool(const bson_iter_t *iter ARG_UNUSED, const char *key, bool v_bool, void *data) /* {{{ */ { #if PHP_VERSION_ID >= 70000 zval *retval = &((php_phongo_bson_state *)data)->zchild; #else zval *retval = ((php_phongo_bson_state *)data)->zchild; #endif add_assoc_bool(retval, key, v_bool); return false; } /* }}} */ bool php_phongo_bson_visit_date_time(const bson_iter_t *iter ARG_UNUSED, const char *key, int64_t msec_since_epoch, void *data) /* {{{ */ { #if PHP_VERSION_ID >= 70000 zval *retval = &((php_phongo_bson_state *)data)->zchild; #else zval *retval = ((php_phongo_bson_state *)data)->zchild; #endif #if PHP_VERSION_ID >= 70000 zval zchild; php_phongo_new_utcdatetime_from_epoch(&zchild, msec_since_epoch TSRMLS_CC); ADD_ASSOC_ZVAL(retval, key, &zchild); #else zval *zchild = NULL; TSRMLS_FETCH(); MAKE_STD_ZVAL(zchild); php_phongo_new_utcdatetime_from_epoch(zchild, msec_since_epoch TSRMLS_CC); ADD_ASSOC_ZVAL(retval, key, zchild); Z_SET_REFCOUNT_P(zchild, 1); #endif return false; } /* }}} */ bool php_phongo_bson_visit_null(const bson_iter_t *iter ARG_UNUSED, const char *key, void *data) /* {{{ */ { #if PHP_VERSION_ID >= 70000 zval *retval = &((php_phongo_bson_state *)data)->zchild; #else zval *retval = ((php_phongo_bson_state *)data)->zchild; #endif add_assoc_null(retval, key); return false; } /* }}} */ bool php_phongo_bson_visit_regex(const bson_iter_t *iter ARG_UNUSED, const char *key, const char *v_regex, const char *v_options, void *data) /* {{{ */ { #if PHP_VERSION_ID >= 70000 zval *retval = &((php_phongo_bson_state *)data)->zchild; #else zval *retval = ((php_phongo_bson_state *)data)->zchild; #endif #if PHP_VERSION_ID >= 70000 zval zchild; php_phongo_new_regex_from_regex_and_options(&zchild, v_regex, v_options TSRMLS_CC); ADD_ASSOC_ZVAL(retval, key, &zchild); #else zval *zchild = NULL; TSRMLS_FETCH(); MAKE_STD_ZVAL(zchild); php_phongo_new_regex_from_regex_and_options(zchild, v_regex, v_options TSRMLS_CC); ADD_ASSOC_ZVAL(retval, key, zchild); Z_SET_REFCOUNT_P(zchild, 1); #endif return false; } /* }}} */ #if 0 bool php_phongo_bson_visit_dbpointer(const bson_iter_t *iter ARG_UNUSED, const char *key, size_t v_collection_len, const char *v_collection, const bson_oid_t *v_oid, void *data) /* {{{ */ { printf("Not Implemented\n"); return true; } /* }}} */ #endif bool php_phongo_bson_visit_code(const bson_iter_t *iter ARG_UNUSED, const char *key, size_t v_code_len, const char *v_code, void *data) /* {{{ */ { #if PHP_VERSION_ID >= 70000 zval *retval = &((php_phongo_bson_state *)data)->zchild; #else zval *retval = ((php_phongo_bson_state *)data)->zchild; #endif #if PHP_VERSION_ID >= 70000 zval zchild; php_phongo_new_javascript_from_javascript(1, &zchild, v_code, v_code_len TSRMLS_CC); ADD_ASSOC_ZVAL(retval, key, &zchild); #else zval *zchild = NULL; TSRMLS_FETCH(); MAKE_STD_ZVAL(zchild); php_phongo_new_javascript_from_javascript(1, zchild, v_code, v_code_len TSRMLS_CC); ADD_ASSOC_ZVAL(retval, key, zchild); Z_SET_REFCOUNT_P(zchild, 1); #endif return false; } /* }}} */ #if 0 bool php_phongo_bson_visit_symbol(const bson_iter_t *iter ARG_UNUSED, const char *key, size_t v_symbol_len, const char *v_symbol, void *data) /* {{{ */ { printf("Not Implemented\n"); return true; } /* }}} */ #endif bool php_phongo_bson_visit_codewscope(const bson_iter_t *iter ARG_UNUSED, const char *key, size_t v_code_len, const char *v_code, const bson_t *v_scope, void *data) /* {{{ */ { #if PHP_VERSION_ID >= 70000 zval *retval = &((php_phongo_bson_state *)data)->zchild; #else zval *retval = ((php_phongo_bson_state *)data)->zchild; #endif #if PHP_VERSION_ID >= 70000 zval zchild; php_phongo_new_javascript_from_javascript_and_scope(1, &zchild, v_code, v_code_len, v_scope TSRMLS_CC); ADD_ASSOC_ZVAL(retval, key, &zchild); #else zval *zchild = NULL; TSRMLS_FETCH(); MAKE_STD_ZVAL(zchild); php_phongo_new_javascript_from_javascript_and_scope(1, zchild, v_code, v_code_len, v_scope TSRMLS_CC); ADD_ASSOC_ZVAL(retval, key, zchild); Z_SET_REFCOUNT_P(zchild, 1); #endif return false; } /* }}} */ bool php_phongo_bson_visit_int32(const bson_iter_t *iter ARG_UNUSED, const char *key, int32_t v_int32, void *data) /* {{{ */ { #if PHP_VERSION_ID >= 70000 zval *retval = &((php_phongo_bson_state *)data)->zchild; #else zval *retval = ((php_phongo_bson_state *)data)->zchild; #endif add_assoc_long(retval, key, v_int32); return false; } /* }}} */ bool php_phongo_bson_visit_timestamp(const bson_iter_t *iter ARG_UNUSED, const char *key, uint32_t v_timestamp, uint32_t v_increment, void *data) /* {{{ */ { #if PHP_VERSION_ID >= 70000 zval *retval = &((php_phongo_bson_state *)data)->zchild; #else zval *retval = ((php_phongo_bson_state *)data)->zchild; #endif #if PHP_VERSION_ID >= 70000 zval zchild; php_phongo_new_timestamp_from_increment_and_timestamp(&zchild, v_increment, v_timestamp TSRMLS_CC); ADD_ASSOC_ZVAL(retval, key, &zchild); #else zval *zchild = NULL; TSRMLS_FETCH(); MAKE_STD_ZVAL(zchild); php_phongo_new_timestamp_from_increment_and_timestamp(zchild, v_increment, v_timestamp TSRMLS_CC); ADD_ASSOC_ZVAL(retval, key, zchild); Z_SET_REFCOUNT_P(zchild, 1); #endif return false; } /* }}} */ bool php_phongo_bson_visit_int64(const bson_iter_t *iter ARG_UNUSED, const char *key, int64_t v_int64, void *data) /* {{{ */ { #if PHP_VERSION_ID >= 70000 zval *retval = &((php_phongo_bson_state *)data)->zchild; #else zval *retval = ((php_phongo_bson_state *)data)->zchild; #endif ADD_ASSOC_INT64(retval, key, v_int64); return false; } /* }}} */ bool php_phongo_bson_visit_maxkey(const bson_iter_t *iter ARG_UNUSED, const char *key, void *data) /* {{{ */ { #if PHP_VERSION_ID >= 70000 zval *retval = &((php_phongo_bson_state *)data)->zchild; #else zval *retval = ((php_phongo_bson_state *)data)->zchild; #endif #if PHP_VERSION_ID >= 70000 zval zchild; object_init_ex(&zchild, php_phongo_maxkey_ce); ADD_ASSOC_ZVAL(retval, key, &zchild); #else zval *zchild = NULL; TSRMLS_FETCH(); MAKE_STD_ZVAL(zchild); object_init_ex(zchild, php_phongo_maxkey_ce); ADD_ASSOC_ZVAL(retval, key, zchild); Z_SET_REFCOUNT_P(zchild, 1); #endif return false; } /* }}} */ bool php_phongo_bson_visit_minkey(const bson_iter_t *iter ARG_UNUSED, const char *key, void *data) /* {{{ */ { #if PHP_VERSION_ID >= 70000 zval *retval = &((php_phongo_bson_state *)data)->zchild; #else zval *retval = ((php_phongo_bson_state *)data)->zchild; #endif #if PHP_VERSION_ID >= 70000 zval zchild; object_init_ex(&zchild, php_phongo_minkey_ce); ADD_ASSOC_ZVAL(retval, key, &zchild); #else zval *zchild = NULL; TSRMLS_FETCH(); MAKE_STD_ZVAL(zchild); object_init_ex(zchild, php_phongo_minkey_ce); Z_SET_REFCOUNT_P(zchild, 1); ADD_ASSOC_ZVAL(retval, key, zchild); #endif return false; } /* }}} */ static const bson_visitor_t php_bson_visitors = { NULL /* php_phongo_bson_visit_before*/, NULL /*php_phongo_bson_visit_after*/, php_phongo_bson_visit_corrupt, php_phongo_bson_visit_double, php_phongo_bson_visit_utf8, php_phongo_bson_visit_document, php_phongo_bson_visit_array, php_phongo_bson_visit_binary, NULL /*php_phongo_bson_visit_undefined*/, php_phongo_bson_visit_oid, php_phongo_bson_visit_bool, php_phongo_bson_visit_date_time, php_phongo_bson_visit_null, php_phongo_bson_visit_regex, NULL /*php_phongo_bson_visit_dbpointer*/, php_phongo_bson_visit_code, NULL /*php_phongo_bson_visit_symbol*/, php_phongo_bson_visit_codewscope, php_phongo_bson_visit_int32, php_phongo_bson_visit_timestamp, php_phongo_bson_visit_int64, php_phongo_bson_visit_maxkey, php_phongo_bson_visit_minkey, { NULL } }; bool php_phongo_bson_visit_document(const bson_iter_t *iter ARG_UNUSED, const char *key, const bson_t *v_document, void *data) { #if PHP_VERSION_ID >= 70000 zval *retval = &((php_phongo_bson_state *)data)->zchild; #else zval *retval = ((php_phongo_bson_state *)data)->zchild; #endif bson_iter_t child; TSRMLS_FETCH(); if (bson_iter_init(&child, v_document)) { php_phongo_bson_state state = PHONGO_BSON_STATE_INITIALIZER; state.map = ((php_phongo_bson_state *)data)->map; #if PHP_VERSION_ID >= 70000 array_init(&state.zchild); #else MAKE_STD_ZVAL(state.zchild); array_init(state.zchild); #endif if (!bson_iter_visit_all(&child, &php_bson_visitors, &state) && !child.err_off) { /* If php_phongo_bson_visit_binary() finds an ODM class, it should * supersede a default type map and named document class. */ if (state.odm && state.map.document_type == PHONGO_TYPEMAP_NONE) { state.map.document_type = PHONGO_TYPEMAP_CLASS; } switch(state.map.document_type) { case PHONGO_TYPEMAP_NATIVE_ARRAY: #if PHP_VERSION_ID >= 70000 ADD_ASSOC_ZVAL(retval, key, &state.zchild); Z_SET_REFCOUNT(state.zchild, 1); #else ADD_ASSOC_ZVAL(retval, key, state.zchild); Z_SET_REFCOUNT_P(state.zchild, 1); #endif break; case PHONGO_TYPEMAP_CLASS: { #if PHP_VERSION_ID >= 70000 zval obj; object_init_ex(&obj, state.odm ? state.odm : state.map.document); zend_call_method_with_1_params(&obj, NULL, NULL, BSON_UNSERIALIZE_FUNC_NAME, NULL, &state.zchild); add_assoc_zval(retval, key, &obj); zval_ptr_dtor(&state.zchild); #else zval *obj = NULL; MAKE_STD_ZVAL(obj); object_init_ex(obj, state.odm ? state.odm : state.map.document); zend_call_method_with_1_params(&obj, NULL, NULL, BSON_UNSERIALIZE_FUNC_NAME, NULL, state.zchild); add_assoc_zval(retval, key, obj); zval_ptr_dtor(&state.zchild); #endif break; } case PHONGO_TYPEMAP_NATIVE_OBJECT: default: #if PHP_VERSION_ID >= 70000 object_and_properties_init(&state.zchild, zend_standard_class_def, Z_ARRVAL(state.zchild)); add_assoc_zval(retval, key, &state.zchild); Z_SET_REFCOUNT(state.zchild, 1); #else object_and_properties_init(state.zchild, zend_standard_class_def, Z_ARRVAL_P(state.zchild)); add_assoc_zval(retval, key, state.zchild); Z_SET_REFCOUNT_P(state.zchild, 1); #endif } } else { /* Iteration stopped prematurely due to corruption or a failed * visitor. Free state.zchild, which we just initialized, and return * true to stop iteration for our parent context. */ zval_ptr_dtor(&state.zchild); return true; } } return false; } bool php_phongo_bson_visit_array(const bson_iter_t *iter ARG_UNUSED, const char *key, const bson_t *v_array, void *data) { #if PHP_VERSION_ID >= 70000 zval *retval = &((php_phongo_bson_state *)data)->zchild; #else zval *retval = ((php_phongo_bson_state *)data)->zchild; #endif bson_iter_t child; TSRMLS_FETCH(); if (bson_iter_init(&child, v_array)) { php_phongo_bson_state state = PHONGO_BSON_STATE_INITIALIZER; state.map = ((php_phongo_bson_state *)data)->map; #if PHP_VERSION_ID >= 70000 array_init(&state.zchild); #else MAKE_STD_ZVAL(state.zchild); array_init(state.zchild); #endif if (!bson_iter_visit_all(&child, &php_bson_visitors, &state) && !child.err_off) { switch(state.map.array_type) { case PHONGO_TYPEMAP_CLASS: { #if PHP_VERSION_ID >= 70000 zval obj; object_init_ex(&obj, state.map.array); zend_call_method_with_1_params(&obj, NULL, NULL, BSON_UNSERIALIZE_FUNC_NAME, NULL, &state.zchild); add_assoc_zval(retval, key, &obj); zval_ptr_dtor(&state.zchild); #else zval *obj = NULL; MAKE_STD_ZVAL(obj); object_init_ex(obj, state.map.array); zend_call_method_with_1_params(&obj, NULL, NULL, BSON_UNSERIALIZE_FUNC_NAME, NULL, state.zchild); add_assoc_zval(retval, key, obj); zval_ptr_dtor(&state.zchild); #endif break; } case PHONGO_TYPEMAP_NATIVE_OBJECT: #if PHP_VERSION_ID >= 70000 object_and_properties_init(&state.zchild, zend_standard_class_def, Z_ARRVAL(state.zchild)); add_assoc_zval(retval, key, &state.zchild); Z_SET_REFCOUNT(state.zchild, 1); #else object_and_properties_init(state.zchild, zend_standard_class_def, Z_ARRVAL_P(state.zchild)); add_assoc_zval(retval, key, state.zchild); Z_SET_REFCOUNT_P(state.zchild, 1); #endif break; case PHONGO_TYPEMAP_NATIVE_ARRAY: default: #if PHP_VERSION_ID >= 70000 ADD_ASSOC_ZVAL(retval, key, &state.zchild); Z_SET_REFCOUNT(state.zchild, 1); #else ADD_ASSOC_ZVAL(retval, key, state.zchild); Z_SET_REFCOUNT_P(state.zchild, 1); #endif break; } } else { /* Iteration stopped prematurely due to corruption or a failed * visitor. Free state.zchild, which we just initialized, and return * true to stop iteration for our parent context. */ zval_ptr_dtor(&state.zchild); return true; } } return false; } int php_phongo_is_array_or_document(zval *val TSRMLS_DC) /* {{{ */ { HashTable *ht_data = HASH_OF(val); int count; if (Z_TYPE_P(val) != IS_ARRAY) { return IS_OBJECT; } count = ht_data ? zend_hash_num_elements(ht_data) : 0; if (count > 0) { #if PHP_VERSION_ID >= 70000 zend_string *key; zend_ulong index, idx; idx = 0; ZEND_HASH_FOREACH_KEY(ht_data, index, key) { if (key) { return IS_OBJECT; } else { if (index != idx) { return IS_OBJECT; } } idx++; } ZEND_HASH_FOREACH_END(); #else char *key; unsigned int key_len; unsigned long index = 0; unsigned long idx = 0; int hash_type = 0; HashPosition pos; zend_hash_internal_pointer_reset_ex(ht_data, &pos); for (;; zend_hash_move_forward_ex(ht_data, &pos)) { hash_type = zend_hash_get_current_key_ex(ht_data, &key, &key_len, &index, 0, &pos); if (hash_type == HASH_KEY_NON_EXISTENT) { break; } if (hash_type == HASH_KEY_IS_STRING) { return IS_OBJECT; } else { if (index != idx) { return IS_OBJECT; } } idx++; } #endif } else { return Z_TYPE_P(val); } return IS_ARRAY; } /* }}} */ void object_to_bson(zval *object, php_phongo_bson_flags_t flags, const char *key, long key_len, bson_t *bson TSRMLS_DC) { bson_t child; if (Z_TYPE_P(object) == IS_OBJECT && instanceof_function(Z_OBJCE_P(object), php_phongo_type_ce TSRMLS_CC)) { if (instanceof_function(Z_OBJCE_P(object), php_phongo_serializable_ce TSRMLS_CC)) { #if PHP_VERSION_ID >= 70000 zval obj_data; #else zval *obj_data = NULL; #endif bson_t child; HashTable *tmp_ht; #if PHP_VERSION_ID >= 70000 zend_call_method_with_0_params(object, NULL, NULL, BSON_SERIALIZE_FUNC_NAME, &obj_data); #else zend_call_method_with_0_params(&object, NULL, NULL, BSON_SERIALIZE_FUNC_NAME, &obj_data); #endif if (Z_ISUNDEF(obj_data)) { /* zend_call_method() failed */ return; } #if PHP_VERSION_ID >= 70000 if (Z_TYPE(obj_data) != IS_ARRAY && !(Z_TYPE(obj_data) == IS_OBJECT && instanceof_function(Z_OBJCE(obj_data), zend_standard_class_def TSRMLS_CC))) { phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "Expected %s::%s() to return an array or stdClass, %s given", Z_OBJCE_P(object)->name->val, BSON_SERIALIZE_FUNC_NAME, (Z_TYPE(obj_data) == IS_OBJECT ? Z_OBJCE(obj_data)->name->val : zend_get_type_by_const(Z_TYPE(obj_data)) ) ); zval_ptr_dtor(&obj_data); #else if (Z_TYPE_P(obj_data) != IS_ARRAY && !(Z_TYPE_P(obj_data) == IS_OBJECT && instanceof_function(Z_OBJCE_P(obj_data), zend_standard_class_def TSRMLS_CC))) { phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "Expected %s::%s() to return an array or stdClass, %s given", Z_OBJCE_P(object)->name, BSON_SERIALIZE_FUNC_NAME, (Z_TYPE_P(obj_data) == IS_OBJECT ? Z_OBJCE_P(obj_data)->name : zend_get_type_by_const(Z_TYPE_P(obj_data)) ) ); zval_ptr_dtor(&obj_data); #endif return; } #if PHP_VERSION_ID >= 70000 tmp_ht = HASH_OF(&obj_data); #else tmp_ht = HASH_OF(obj_data); #endif if (tmp_ht) { ZEND_HASH_APPLY_COUNT(tmp_ht)++; } /* Persistable objects must always be serialized as BSON documents; * otherwise, infer based on bsonSerialize()'s return value. */ #if PHP_VERSION_ID >= 70000 if (instanceof_function(Z_OBJCE_P(object), php_phongo_persistable_ce TSRMLS_CC) || php_phongo_is_array_or_document(&obj_data TSRMLS_CC) == IS_OBJECT) { #else if (instanceof_function(Z_OBJCE_P(object), php_phongo_persistable_ce TSRMLS_CC) || php_phongo_is_array_or_document(obj_data TSRMLS_CC) == IS_OBJECT) { #endif bson_append_document_begin(bson, key, key_len, &child); if (instanceof_function(Z_OBJCE_P(object), php_phongo_persistable_ce TSRMLS_CC)) { #if PHP_VERSION_ID >= 70000 bson_append_binary(&child, PHONGO_ODM_FIELD_NAME, -1, 0x80, (const uint8_t *)Z_OBJCE_P(object)->name->val, Z_OBJCE_P(object)->name->len); #else bson_append_binary(&child, PHONGO_ODM_FIELD_NAME, -1, 0x80, (const uint8_t *)Z_OBJCE_P(object)->name, strlen(Z_OBJCE_P(object)->name)); #endif } #if PHP_VERSION_ID >= 70000 phongo_zval_to_bson(&obj_data, flags, &child, NULL TSRMLS_CC); #else phongo_zval_to_bson(obj_data, flags, &child, NULL TSRMLS_CC); #endif bson_append_document_end(bson, &child); } else { bson_append_array_begin(bson, key, key_len, &child); #if PHP_VERSION_ID >= 70000 phongo_zval_to_bson(&obj_data, flags, &child, NULL TSRMLS_CC); #else phongo_zval_to_bson(obj_data, flags, &child, NULL TSRMLS_CC); #endif bson_append_array_end(bson, &child); } if (tmp_ht) { ZEND_HASH_APPLY_COUNT(tmp_ht)--; } zval_ptr_dtor(&obj_data); return; } if (instanceof_function(Z_OBJCE_P(object), php_phongo_objectid_ce TSRMLS_CC)) { bson_oid_t oid; mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding ObjectId"); php_phongo_objectid_get_id(object, &oid TSRMLS_CC); bson_append_oid(bson, key, key_len, &oid); return; } if (instanceof_function(Z_OBJCE_P(object), php_phongo_utcdatetime_ce TSRMLS_CC)) { mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding UTCDateTime"); bson_append_date_time(bson, key, key_len, php_phongo_utcdatetime_get_milliseconds(object TSRMLS_CC)); return; } if (instanceof_function(Z_OBJCE_P(object), php_phongo_binary_ce TSRMLS_CC)) { const unsigned char *data; size_t data_len; data_len = php_phongo_binary_get_data(object, (char **)&data TSRMLS_CC); mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding Binary"); bson_append_binary(bson, key, key_len, php_phongo_binary_get_type(object TSRMLS_CC), data, data_len); return; } if (instanceof_function(Z_OBJCE_P(object), php_phongo_regex_ce TSRMLS_CC)) { mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding Regex"); bson_append_regex(bson, key, key_len, php_phongo_regex_get_pattern(object TSRMLS_CC), php_phongo_regex_get_flags(object TSRMLS_CC)); return; } if (instanceof_function(Z_OBJCE_P(object), php_phongo_javascript_ce TSRMLS_CC)) { if (php_phongo_javascript_has_scope(object TSRMLS_CC)) { mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding Javascript with scope"); bson_append_code(bson, key, key_len, php_phongo_javascript_get_javascript(object TSRMLS_CC)); } else { mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding Javascript without scope"); bson_append_code_with_scope(bson, key, key_len, php_phongo_javascript_get_javascript(object TSRMLS_CC), php_phongo_javascript_get_scope(object TSRMLS_CC)); } return; } if (instanceof_function(Z_OBJCE_P(object), php_phongo_timestamp_ce TSRMLS_CC)) { mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding Timestamp"); /* * WHOOPS! libbson swaps the increment/timestamp compared to BSON * * "Timestamp - Special internal type used by MongoDB replication and sharding. * First 4 bytes are an increment, second 4 are a timestamp." */ bson_append_timestamp(bson, key, key_len, php_phongo_timestamp_get_timestamp(object TSRMLS_CC), php_phongo_timestamp_get_increment(object TSRMLS_CC)); return; } if (instanceof_function(Z_OBJCE_P(object), php_phongo_maxkey_ce TSRMLS_CC)) { mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding MaxKey"); bson_append_maxkey(bson, key, key_len); return; } if (instanceof_function(Z_OBJCE_P(object), php_phongo_minkey_ce TSRMLS_CC)) { mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding MinKey"); bson_append_minkey(bson, key, key_len); return; } #if PHP_VERSION_ID >= 70000 phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "Unexpected %s instance: %s", ZSTR_VAL(php_phongo_type_ce->name), ZSTR_VAL(Z_OBJCE_P(object)->name)); #else phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "Unexpected %s instance: %s", php_phongo_type_ce->name, Z_OBJCE_P(object)->name); #endif return; } mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "encoding document"); bson_append_document_begin(bson, key, key_len, &child); phongo_zval_to_bson(object, flags, &child, NULL TSRMLS_CC); bson_append_document_end(bson, &child); } static void phongo_bson_append(bson_t *bson, php_phongo_bson_flags_t flags, const char *key, long key_len, zval *entry TSRMLS_DC) { #if PHP_VERSION_ID >= 70000 try_again: #endif switch (Z_TYPE_P(entry)) { case IS_NULL: bson_append_null(bson, key, key_len); break; #if PHP_VERSION_ID >= 70000 case IS_TRUE: bson_append_bool(bson, key, key_len, true); break; case IS_FALSE: bson_append_bool(bson, key, key_len, false); break; #else case IS_BOOL: bson_append_bool(bson, key, key_len, Z_BVAL_P(entry)); break; #endif case IS_LONG: BSON_APPEND_INT(bson, key, key_len, Z_LVAL_P(entry)); break; case IS_DOUBLE: bson_append_double(bson, key, key_len, Z_DVAL_P(entry)); break; case IS_STRING: if (bson_utf8_validate(Z_STRVAL_P(entry), Z_STRLEN_P(entry), true)) { bson_append_utf8(bson, key, key_len, Z_STRVAL_P(entry), Z_STRLEN_P(entry)); } else { phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "Got invalid UTF-8 value serializing '%s'", Z_STRVAL_P(entry)); } break; case IS_ARRAY: if (php_phongo_is_array_or_document(entry TSRMLS_CC) == IS_ARRAY) { bson_t child; HashTable *tmp_ht = HASH_OF(entry); if (tmp_ht) { ZEND_HASH_APPLY_COUNT(tmp_ht)++; } bson_append_array_begin(bson, key, key_len, &child); phongo_zval_to_bson(entry, flags, &child, NULL TSRMLS_CC); bson_append_array_end(bson, &child); if (tmp_ht) { ZEND_HASH_APPLY_COUNT(tmp_ht)--; } break; } /* break intentionally omitted */ case IS_OBJECT: object_to_bson(entry, flags, key, key_len, bson TSRMLS_CC); break; #if PHP_VERSION_ID >= 70000 case IS_INDIRECT: phongo_bson_append(bson, flags, key, key_len, Z_INDIRECT_P(entry) TSRMLS_DC); break; case IS_REFERENCE: ZVAL_DEREF(entry); goto try_again; #endif default: phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "Got unsupported type %d '%s'", Z_TYPE_P(entry), zend_get_type_by_const(Z_TYPE_P(entry))); } } #if PHP_VERSION_ID >= 70000 static bool is_public_property(zend_class_entry *ce, zend_string *name, zend_string **member TSRMLS_DC) /* {{{ */ #else static bool is_public_property(zend_class_entry *ce, const char *prop_name, int prop_name_len TSRMLS_DC) /* {{{ */ #endif { zend_property_info *property_info = NULL; #if PHP_VERSION_ID >= 70000 if (ZSTR_VAL(name)[0] == 0) { const char *prop_name, *class_name; size_t prop_name_len; zend_unmangle_property_name_ex(name, &class_name, &prop_name, &prop_name_len); (*member) = zend_string_init(prop_name, prop_name_len, 0); } else (*member) = zend_string_copy(name); property_info = zend_get_property_info(ce, (*member), 1 TSRMLS_CC); if (!property_info) /* undefined property */ return true; if (property_info == ZEND_WRONG_PROPERTY_INFO) { return false; } return (property_info->flags & ZEND_ACC_PUBLIC); #else zval member; ZVAL_STRINGL(&member, prop_name, prop_name_len, 0); property_info = zend_get_property_info(ce, &member, 1 TSRMLS_CC); return (property_info && (property_info->flags & ZEND_ACC_PUBLIC)); #endif } /* }}} */ PHONGO_API void phongo_zval_to_bson(zval *data, php_phongo_bson_flags_t flags, bson_t *bson, bson_t **bson_out TSRMLS_DC) /* {{{ */ { HashTable *ht_data = NULL; #if PHP_VERSION_ID >= 70000 zval obj_data; #else HashPosition pos; zval *obj_data = NULL; #endif /* If we will be encoding a class that may contain protected and private * properties, we'll need to filter them out later. */ bool ht_data_from_properties = false; switch(Z_TYPE_P(data)) { case IS_OBJECT: if (instanceof_function(Z_OBJCE_P(data), php_phongo_serializable_ce TSRMLS_CC)) { #if PHP_VERSION_ID >= 70000 zend_call_method_with_0_params(data, NULL, NULL, BSON_SERIALIZE_FUNC_NAME, &obj_data); #else zend_call_method_with_0_params(&data, NULL, NULL, BSON_SERIALIZE_FUNC_NAME, &obj_data); #endif if (Z_ISUNDEF(obj_data)) { /* zend_call_method() failed */ break; } #if PHP_VERSION_ID >= 70000 if (Z_TYPE(obj_data) != IS_ARRAY && !(Z_TYPE(obj_data) == IS_OBJECT && instanceof_function(Z_OBJCE(obj_data), zend_standard_class_def TSRMLS_CC))) { #else if (Z_TYPE_P(obj_data) != IS_ARRAY && !(Z_TYPE_P(obj_data) == IS_OBJECT && instanceof_function(Z_OBJCE_P(obj_data), zend_standard_class_def TSRMLS_CC))) { #endif phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "Expected %s::%s() to return an array or stdClass, %s given", #if PHP_VERSION_ID >= 70000 Z_OBJCE_P(data)->name->val, #else Z_OBJCE_P(data)->name, #endif BSON_SERIALIZE_FUNC_NAME, #if PHP_VERSION_ID >= 70000 (Z_TYPE(obj_data) == IS_OBJECT ? Z_OBJCE(obj_data)->name->val : zend_get_type_by_const(Z_TYPE(obj_data)) #else (Z_TYPE_P(obj_data) == IS_OBJECT ? Z_OBJCE_P(obj_data)->name : zend_get_type_by_const(Z_TYPE_P(obj_data)) #endif ) ); break; } #if PHP_VERSION_ID >= 70000 ht_data = HASH_OF(&obj_data); #else ht_data = HASH_OF(obj_data); #endif if (instanceof_function(Z_OBJCE_P(data), php_phongo_persistable_ce TSRMLS_CC)) { #if PHP_VERSION_ID >= 70000 bson_append_binary(bson, PHONGO_ODM_FIELD_NAME, -1, 0x80, (const uint8_t *)Z_OBJCE_P(data)->name->val, Z_OBJCE_P(data)->name->len); zend_hash_str_del(ht_data, PHONGO_ODM_FIELD_NAME, sizeof(PHONGO_ODM_FIELD_NAME)-1); #else bson_append_binary(bson, PHONGO_ODM_FIELD_NAME, -1, 0x80, (const uint8_t *)Z_OBJCE_P(data)->name, strlen(Z_OBJCE_P(data)->name)); zend_hash_del(ht_data, PHONGO_ODM_FIELD_NAME, sizeof(PHONGO_ODM_FIELD_NAME)); #endif } break; } if (instanceof_function(Z_OBJCE_P(data), php_phongo_type_ce TSRMLS_CC)) { #if PHP_VERSION_ID >= 70000 phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "%s instance %s cannot be serialized as a root element", ZSTR_VAL(php_phongo_type_ce->name), ZSTR_VAL(Z_OBJCE_P(data)->name)); #else phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "%s instance %s cannot be serialized as a root element", php_phongo_type_ce->name, Z_OBJCE_P(data)->name); #endif break; } ht_data = Z_OBJ_HT_P(data)->get_properties(data TSRMLS_CC); ht_data_from_properties = true; break; case IS_ARRAY: ht_data = HASH_OF(data); break; default: return; } if (!ht_data || ZEND_HASH_APPLY_COUNT(ht_data) > 1) { #if PHP_VERSION_ID >= 70000 if (Z_TYPE_P(data) == IS_OBJECT && instanceof_function(Z_OBJCE_P(data), php_phongo_serializable_ce TSRMLS_CC)) { #endif if (!Z_ISUNDEF(obj_data)) { zval_ptr_dtor(&obj_data); } #if PHP_VERSION_ID >= 70000 } #endif return; } #if PHP_VERSION_ID >= 70000 { zend_string *string_key = NULL; zend_ulong num_key = 0; zval *value; ZEND_HASH_FOREACH_KEY_VAL(ht_data, num_key, string_key, value) { /* Ensure we're working with a string key */ if (!string_key) { string_key = zend_long_to_str(num_key); } else { zend_string_addref(string_key); } if (Z_TYPE_P(data) == IS_OBJECT) { zend_string *member = NULL; /* Ignore non-public properties */ if (!instanceof_function(Z_OBJCE_P(data), php_phongo_serializable_ce) && !is_public_property(Z_OBJCE_P(data), string_key, &member TSRMLS_CC)) { if (member) { zend_string_release(member); } zend_string_release(string_key); continue; } if (flags & PHONGO_BSON_ADD_ID) { if (!strncmp(member ? ZSTR_VAL(member) : ZSTR_VAL(string_key), "_id", sizeof("_id")-1)) { flags &= ~PHONGO_BSON_ADD_ID; } } phongo_bson_append(bson, flags & ~PHONGO_BSON_ADD_ID, member ? ZSTR_VAL(member) : ZSTR_VAL(string_key), member ? ZSTR_LEN(member) : ZSTR_LEN(string_key), value TSRMLS_CC); if (member) { zend_string_release(member); } } else { if (flags & PHONGO_BSON_ADD_ID) { if (!strncmp(ZSTR_VAL(string_key), "_id", sizeof("_id")-1)) { flags &= ~PHONGO_BSON_ADD_ID; } } phongo_bson_append(bson, flags & ~PHONGO_BSON_ADD_ID, ZSTR_VAL(string_key), ZSTR_LEN(string_key), value TSRMLS_CC); } zend_string_release(string_key); } ZEND_HASH_FOREACH_END(); } #else zend_hash_internal_pointer_reset_ex(ht_data, &pos); for (;; zend_hash_move_forward_ex(ht_data, &pos)) { char *string_key = NULL; uint string_key_len = 0; ulong num_key = 0; zval **value; int hash_type; hash_type = zend_hash_get_current_key_ex(ht_data, &string_key, &string_key_len, &num_key, 0, &pos); if (hash_type == HASH_KEY_NON_EXISTENT) { break; } if (zend_hash_get_current_data_ex(ht_data, (void **) &value, &pos) == FAILURE) { break; } if (hash_type == HASH_KEY_IS_STRING) { if (ht_data_from_properties) { const char *class_name; zend_unmangle_property_name(string_key, string_key_len-1, &class_name, (const char **)&string_key); string_key_len = strlen(string_key); /* Ignore non-public properties */ if (!is_public_property(Z_OBJCE_P(data), string_key, string_key_len TSRMLS_CC)) { continue; } } else { /* Chop off the \0 from string lengths */ string_key_len -= 1; } if (flags & PHONGO_BSON_ADD_ID) { if (!strncmp(string_key, "_id", sizeof("_id")-1)) { flags &= ~PHONGO_BSON_ADD_ID; } } } /* Ensure we're working with a string key */ if (hash_type == HASH_KEY_IS_LONG) { spprintf(&string_key, 0, "%ld", num_key); string_key_len = strlen(string_key); } phongo_bson_append(bson, flags & ~PHONGO_BSON_ADD_ID, string_key, string_key_len, *value TSRMLS_CC); if (hash_type == HASH_KEY_IS_LONG) { efree(string_key); } } #endif if (flags & PHONGO_BSON_ADD_ID) { bson_oid_t oid; bson_oid_init(&oid, NULL); bson_append_oid(bson, "_id", strlen("_id"), &oid); mongoc_log(MONGOC_LOG_LEVEL_TRACE, MONGOC_LOG_DOMAIN, "Added new _id"); if (flags & PHONGO_BSON_RETURN_ID) { if (bson_out) { *bson_out = bson_new(); bson_append_oid(*bson_out, "_id", strlen("_id"), &oid); } } } #if PHP_VERSION_ID >= 70000 if (Z_TYPE_P(data) == IS_OBJECT && instanceof_function(Z_OBJCE_P(data), php_phongo_serializable_ce TSRMLS_CC)) { #endif if (!Z_ISUNDEF(obj_data)) { zval_ptr_dtor(&obj_data); } #if PHP_VERSION_ID >= 70000 } #endif } /* }}} */ #if PHP_VERSION_ID >= 70000 PHONGO_API int phongo_bson_to_zval(const unsigned char *data, int data_len, zval *zv) #else PHONGO_API int phongo_bson_to_zval(const unsigned char *data, int data_len, zval **zv) #endif { int retval = 0; php_phongo_bson_state state = PHONGO_BSON_STATE_INITIALIZER; retval = phongo_bson_to_zval_ex(data, data_len, &state); #if PHP_VERSION_ID >= 70000 ZVAL_ZVAL(zv, &state.zchild, 1, 1); #else *zv = state.zchild; #endif return retval; } PHONGO_API int phongo_bson_to_zval_ex(const unsigned char *data, int data_len, php_phongo_bson_state *state) { bson_reader_t *reader; bson_iter_t iter; const bson_t *b; bool eof = false; TSRMLS_FETCH(); #if PHP_VERSION_ID < 70000 MAKE_STD_ZVAL(state->zchild); /* Ensure that state->zchild has a type, since the calling code may want to * zval_ptr_dtor() it if we throw an exception. */ ZVAL_NULL(state->zchild); #endif reader = bson_reader_new_from_data(data, data_len); if (!(b = bson_reader_read(reader, NULL))) { phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "Could not read document from BSON reader"); bson_reader_destroy(reader); return 0; } if (!bson_iter_init(&iter, b)) { phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "Could not initialize BSON iterator"); bson_reader_destroy(reader); return 0; } /* We initialize an array because it will either be returned as-is (native * array in type map), passed to bsonUnserialize() (ODM class), or used to * initialize a stdClass object (native object in type map). */ #if PHP_VERSION_ID >= 70000 array_init(&state->zchild); #else array_init(state->zchild); #endif if (bson_iter_visit_all(&iter, &php_bson_visitors, state) || iter.err_off) { /* Iteration stopped prematurely due to corruption or a failed visitor. * While we free the reader, state->zchild should be left as-is, since * the calling code may want to zval_ptr_dtor() it. */ phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "Could not convert BSON document to a PHP variable"); bson_reader_destroy(reader); return 0; } /* If php_phongo_bson_visit_binary() finds an ODM class, it should supersede * a default type map and named root class. */ if (state->odm && state->map.root_type == PHONGO_TYPEMAP_NONE) { state->map.root_type = PHONGO_TYPEMAP_CLASS; } switch (state->map.root_type) { case PHONGO_TYPEMAP_NATIVE_ARRAY: /* Nothing to do here */ break; case PHONGO_TYPEMAP_CLASS: { #if PHP_VERSION_ID >= 70000 zval obj; object_init_ex(&obj, state->odm ? state->odm : state->map.root); zend_call_method_with_1_params(&obj, NULL, NULL, BSON_UNSERIALIZE_FUNC_NAME, NULL, &state->zchild); zval_ptr_dtor(&state->zchild); ZVAL_COPY_VALUE(&state->zchild, &obj); #else zval *obj = NULL; MAKE_STD_ZVAL(obj); object_init_ex(obj, state->odm ? state->odm : state->map.root); zend_call_method_with_1_params(&obj, NULL, NULL, BSON_UNSERIALIZE_FUNC_NAME, NULL, state->zchild); zval_ptr_dtor(&state->zchild); state->zchild = obj; #endif break; } case PHONGO_TYPEMAP_NATIVE_OBJECT: default: #if PHP_VERSION_ID >= 70000 object_and_properties_init(&state->zchild, zend_standard_class_def, Z_ARRVAL(state->zchild)); #else object_and_properties_init(state->zchild, zend_standard_class_def, Z_ARRVAL_P(state->zchild)); #endif } if (bson_reader_read(reader, &eof) || !eof) { phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "Reading document did not exhaust input buffer"); bson_reader_destroy(reader); return 0; } bson_reader_destroy(reader); return 1; } /* {{{ proto string BSON\fromPHP(array|object $value) Returns the BSON representation of a PHP value */ PHP_FUNCTION(fromPHP) { zval *data; bson_t *bson; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(this_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) /* We don't use these */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "A", &data) == FAILURE) { return; } bson = bson_new(); phongo_zval_to_bson(data, PHONGO_BSON_NONE, bson, NULL TSRMLS_CC); PHONGO_RETVAL_STRINGL((const char *) bson_get_data(bson), bson->len); bson_destroy(bson); } /* }}} */ static void apply_classname_to_state(const char *classname, int classname_len, php_phongo_bson_typemap_types *type, zend_class_entry **type_ce TSRMLS_DC) { if (!strcasecmp(classname, "array")) { *type = PHONGO_TYPEMAP_NATIVE_ARRAY; *type_ce = NULL; } else if (!strcasecmp(classname, "stdclass") || !strcasecmp(classname, "object")) { *type = PHONGO_TYPEMAP_NATIVE_OBJECT; *type_ce = NULL; } else { #if PHP_VERSION_ID >= 70000 zend_string* zs_classname = zend_string_init(classname, classname_len, 0); zend_class_entry *found_ce = zend_fetch_class(zs_classname, ZEND_FETCH_CLASS_AUTO|ZEND_FETCH_CLASS_SILENT TSRMLS_CC); zend_string_free(zs_classname); #else zend_class_entry *found_ce = zend_fetch_class(classname, classname_len, ZEND_FETCH_CLASS_AUTO|ZEND_FETCH_CLASS_SILENT TSRMLS_CC); #endif if (!found_ce) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Class %s does not exist", classname); } else if (!PHONGO_IS_CLASS_INSTANTIATABLE(found_ce)) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Class %s is not instantiatable", classname); } else if (!instanceof_function(found_ce, php_phongo_unserializable_ce TSRMLS_CC)) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Class %s does not implement %s\\Unserializable", classname, BSON_NAMESPACE); } else { *type = PHONGO_TYPEMAP_CLASS; *type_ce = found_ce; } } } PHONGO_API void phongo_bson_typemap_to_state(zval *typemap, php_phongo_bson_typemap *map TSRMLS_DC) { if (typemap) { char *classname; int classname_len; zend_bool classname_free = 0; classname = php_array_fetchl_string(typemap, "array", sizeof("array")-1, &classname_len, &classname_free); if (classname_len) { apply_classname_to_state(classname, classname_len, &map->array_type, &map->array TSRMLS_CC); } if (classname_free) { str_efree(classname); } classname = php_array_fetchl_string(typemap, "document", sizeof("document")-1, &classname_len, &classname_free); if (classname_len) { apply_classname_to_state(classname, classname_len, &map->document_type, &map->document TSRMLS_CC); } if (classname_free) { str_efree(classname); } classname = php_array_fetchl_string(typemap, "root", sizeof("root")-1, &classname_len, &classname_free); if (classname_len) { apply_classname_to_state(classname, classname_len, &map->root_type, &map->root TSRMLS_CC); } if (classname_free) { str_efree(classname); } } } /* {{{ proto array|object BSON\toPHP(string $bson [, array $typemap = array()]) Returns the PHP representation of a BSON value, optionally converting it into a custom class */ PHP_FUNCTION(toPHP) { char *data; phongo_zpp_char_len data_len; zval *typemap = NULL; php_phongo_bson_state state = PHONGO_BSON_STATE_INITIALIZER; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(this_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) /* We don't use these */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|a!", &data, &data_len, &typemap) == FAILURE) { return; } phongo_bson_typemap_to_state(typemap, &state.map TSRMLS_CC); if (!phongo_bson_to_zval_ex((const unsigned char *)data, data_len, &state)) { zval_ptr_dtor(&state.zchild); RETURN_NULL(); } #if PHP_VERSION_ID >= 70000 RETURN_ZVAL(&state.zchild, 0, 1); #else RETURN_ZVAL(state.zchild, 0, 1); #endif } /* }}} */ /* {{{ proto string BSON\toJSON(string $bson) Returns the JSON representation of a BSON value */ PHP_FUNCTION(toJSON) { char *data; phongo_zpp_char_len data_len; const bson_t *b; bool eof = false; bson_reader_t *reader; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(this_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) /* We don't use these */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &data, &data_len) == FAILURE) { return; } reader = bson_reader_new_from_data((const unsigned char *)data, data_len); b = bson_reader_read(reader, NULL); if (b) { char *str; size_t str_len; str = bson_as_json(b, &str_len); if (!str) { phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "Could not convert BSON document to a JSON string"); bson_reader_destroy(reader); return; } PHONGO_RETVAL_STRINGL(str, str_len); bson_free(str); } else { phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "Could not read document from BSON reader"); bson_reader_destroy(reader); return; } if (bson_reader_read(reader, &eof) || !eof) { phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "Reading document did not exhaust input buffer"); } bson_reader_destroy(reader); } /* }}} */ /* {{{ proto string BSON\fromJSON(string $json) Returns the BSON representation of a JSON value */ PHP_FUNCTION(fromJSON) { char *data; phongo_zpp_char_len data_len; bson_t b = BSON_INITIALIZER; bson_error_t error; SUPPRESS_UNUSED_WARNING(return_value_ptr) SUPPRESS_UNUSED_WARNING(this_ptr) SUPPRESS_UNUSED_WARNING(return_value_used) /* We don't use these */ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &data, &data_len) == FAILURE) { return; } if (bson_init_from_json(&b, (const char *)data, data_len, &error)) { PHONGO_RETVAL_STRINGL((const char *) bson_get_data(&b), b.len); bson_destroy(&b); } else { phongo_throw_exception(PHONGO_ERROR_UNEXPECTED_VALUE TSRMLS_CC, "%s", error.message ? error.message : "Error parsing JSON"); } } /* }}} */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mongodb-1.1.5/tests/bson/bson-binary-001.phpt0000664000175000017500000000645012673034026020534 0ustar jmikolajmikola--TEST-- BSON BSON\Binary #001 --SKIPIF-- --FILE-- getData() == "random binary data"); var_dump($binary->getType() == $type); $tests[] = array("binary" => $binary); } foreach($tests as $n => $test) { $s = fromPHP($test); echo "Test#{$n} ", $json = toJSON($s), "\n"; $bson = fromJSON($json); $testagain = toPHP($bson); var_dump(toJSON(fromPHP($test)), toJSON(fromPHP($testagain))); var_dump((object)$test == (object)$testagain); } ?> ===DONE=== --EXPECTF-- bool(true) bool(true) bool(true) bool(true) bool(true) bool(true) bool(true) bool(true) bool(true) bool(true) bool(true) bool(true) bool(true) bool(true) bool(true) bool(true) Test#0 { "binary" : { "$type" : "00", "$binary" : "cmFuZG9tIGJpbmFyeSBkYXRh" } } string(73) "{ "binary" : { "$type" : "00", "$binary" : "cmFuZG9tIGJpbmFyeSBkYXRh" } }" string(73) "{ "binary" : { "$type" : "00", "$binary" : "cmFuZG9tIGJpbmFyeSBkYXRh" } }" bool(true) Test#1 { "binary" : { "$type" : "01", "$binary" : "cmFuZG9tIGJpbmFyeSBkYXRh" } } string(73) "{ "binary" : { "$type" : "01", "$binary" : "cmFuZG9tIGJpbmFyeSBkYXRh" } }" string(73) "{ "binary" : { "$type" : "01", "$binary" : "cmFuZG9tIGJpbmFyeSBkYXRh" } }" bool(true) Test#2 { "binary" : { "$type" : "02", "$binary" : "cmFuZG9tIGJpbmFyeSBkYXRh" } } string(73) "{ "binary" : { "$type" : "02", "$binary" : "cmFuZG9tIGJpbmFyeSBkYXRh" } }" string(73) "{ "binary" : { "$type" : "02", "$binary" : "cmFuZG9tIGJpbmFyeSBkYXRh" } }" bool(true) Test#3 { "binary" : { "$type" : "03", "$binary" : "cmFuZG9tIGJpbmFyeSBkYXRh" } } string(73) "{ "binary" : { "$type" : "03", "$binary" : "cmFuZG9tIGJpbmFyeSBkYXRh" } }" string(73) "{ "binary" : { "$type" : "03", "$binary" : "cmFuZG9tIGJpbmFyeSBkYXRh" } }" bool(true) Test#4 { "binary" : { "$type" : "04", "$binary" : "cmFuZG9tIGJpbmFyeSBkYXRh" } } string(73) "{ "binary" : { "$type" : "04", "$binary" : "cmFuZG9tIGJpbmFyeSBkYXRh" } }" string(73) "{ "binary" : { "$type" : "04", "$binary" : "cmFuZG9tIGJpbmFyeSBkYXRh" } }" bool(true) Test#5 { "binary" : { "$type" : "05", "$binary" : "cmFuZG9tIGJpbmFyeSBkYXRh" } } string(73) "{ "binary" : { "$type" : "05", "$binary" : "cmFuZG9tIGJpbmFyeSBkYXRh" } }" string(73) "{ "binary" : { "$type" : "05", "$binary" : "cmFuZG9tIGJpbmFyeSBkYXRh" } }" bool(true) Test#6 { "binary" : { "$type" : "80", "$binary" : "cmFuZG9tIGJpbmFyeSBkYXRh" } } string(73) "{ "binary" : { "$type" : "80", "$binary" : "cmFuZG9tIGJpbmFyeSBkYXRh" } }" string(73) "{ "binary" : { "$type" : "80", "$binary" : "cmFuZG9tIGJpbmFyeSBkYXRh" } }" bool(true) Test#7 { "binary" : { "$type" : "85", "$binary" : "cmFuZG9tIGJpbmFyeSBkYXRh" } } string(73) "{ "binary" : { "$type" : "85", "$binary" : "cmFuZG9tIGJpbmFyeSBkYXRh" } }" string(73) "{ "binary" : { "$type" : "85", "$binary" : "cmFuZG9tIGJpbmFyeSBkYXRh" } }" bool(true) ===DONE=== mongodb-1.1.5/tests/bson/bson-binary_error-001.phpt0000664000175000017500000000153412673034026021743 0ustar jmikolajmikola--TEST-- BSON BSON\Binary #001 error --SKIPIF-- --FILE-- getData(2); $binary->getType(2); throws(function() use($classname) { new $classname("random binary data without type"); }, "MongoDB\\Driver\\Exception\\InvalidArgumentException"); ?> ===DONE=== --EXPECTF-- Warning: %s\Binary::getData() expects exactly 0 parameters, 1 given in %s on line %d Warning: %s\Binary::getType() expects exactly 0 parameters, 1 given in %s on line %d OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE=== mongodb-1.1.5/tests/bson/bson-binary_error-002.phpt0000664000175000017500000000057112673034026021744 0ustar jmikolajmikola--TEST-- BSON BSON\Binary cannot be extended --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- Fatal error: Class MyBinary may not inherit from final class (%SBSON\Binary) in %s on line %d mongodb-1.1.5/tests/bson/bson-binary_error-003.phpt0000664000175000017500000000124412673034026021743 0ustar jmikolajmikola--TEST-- BSON BSON\Binary cannot be serialized --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- OK: Got Exception Serialization of '%SBSON\Binary' is not allowed OK: Got Exception Unserialization of '%SBSON\Binary' is not allowed ===DONE=== mongodb-1.1.5/tests/bson/bson-binary_error-004.phpt0000664000175000017500000000137112673034026021745 0ustar jmikolajmikola--TEST-- BSON BSON\Binary constructor requires unsigned 8-bit integer for type --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected type to be an unsigned 8-bit integer, -1 given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected type to be an unsigned 8-bit integer, 256 given ===DONE=== mongodb-1.1.5/tests/bson/bson-decode-001.phpt0000664000175000017500000000402612673034026020470 0ustar jmikolajmikola--TEST-- BSON encoding: Encoding data into BSON representation, and BSON into Extended JSON --SKIPIF-- --FILE-- "world"), array((object)array("hello" => "world")), array(null), array(123), array(4.23), array(true), array(false), array("string"), array("string", true), array('test', 'foo', 'bar'), array('test' => 'test', 'foo' => 'foo', 'bar' => 'bar'), array('foo' => 'test', 'foo', 'bar'), /* (object)array("hello" => "world"), array(array("hello" => "world")), array(array(1, 2, 3, 4, 5, 6, 7, 8, 9)), array((object)array(1, 2, 3, 4, 5, 6, 7, 8, 9)), array(array("0" => 1, "1" => 2, "2" => 3, "3" => 4, "4" => 5, "5" => 6, "6" => 7, "7" => 8, "8" => 9)), array("int" => 3, "boolean" => true, "array" => array("foo", "bar"), "object" => new stdclass, "string" => "test", 3 => "test"), array(array("string", true)), array(array('test', 'foo', 'bar')), array(array('test' => 'test', 'foo' => 'foo', 'bar' => 'bar')), array(array('foo' => 'test', 'foo', 'bar')), array(array("int" => 3, "boolean" => true, "array" => array("foo", "bar"), "object" => new stdclass, "string" => "test", 3 => "test")), */ ); foreach($tests as $n => $test) { $s = fromPHP($test); echo "Test#{$n} ", toJSON($s), "\n"; $val = toPHP($s); if ($val == (object) $test) { echo "OK\n"; } else { var_dump($val, $test); } } ?> ===DONE=== --EXPECT-- Test#0 { "hello" : "world" } OK Test#1 { "0" : { "hello" : "world" } } OK Test#2 { "0" : null } OK Test#3 { "0" : 123 } OK Test#4 { "0" : 4.23 } OK Test#5 { "0" : true } OK Test#6 { "0" : false } OK Test#7 { "0" : "string" } OK Test#8 { "0" : "string", "1" : true } OK Test#9 { "0" : "test", "1" : "foo", "2" : "bar" } OK Test#10 { "test" : "test", "foo" : "foo", "bar" : "bar" } OK Test#11 { "foo" : "test", "0" : "foo", "1" : "bar" } OK ===DONE=== mongodb-1.1.5/tests/bson/bson-decode-002.phpt0000664000175000017500000000530712673034026020474 0ustar jmikolajmikola--TEST-- BSON encoding: Encoding object/arrays data into user specificied classes --SKIPIF-- --FILE-- "world")), array((object)array("hello" => "world")), array("my" => array("hello" => "world")), array("my" => (object)array("hello" => "world")), array("my" => array(array("hello", "world"))), array("my" => (object)array(array("hello", "world"))), ); foreach($tests as $n => $test) { $s = fromPHP($test); echo "Test#{$n} ", toJSON($s), "\n"; $val = toPHP($s, array("root"=> "MyArrayObject", "document"=> "MyArrayObject", "array" => "MyArrayObject")); var_dump($val); } ?> ===DONE=== --EXPECTF-- Test#%d { "0" : { "hello" : "world" } } object(MyArrayObject)#%d (1) { [%s]=> array(1) { [0]=> object(MyArrayObject)#%d (1) { [%s]=> array(1) { ["hello"]=> string(5) "world" } } } } Test#%d { "0" : { "hello" : "world" } } object(MyArrayObject)#%d (1) { [%s]=> array(1) { [0]=> object(MyArrayObject)#%d (1) { [%s]=> array(1) { ["hello"]=> string(5) "world" } } } } Test#%d { "my" : { "hello" : "world" } } object(MyArrayObject)#%d (1) { [%s]=> array(1) { ["my"]=> object(MyArrayObject)#%d (1) { [%s]=> array(1) { ["hello"]=> string(5) "world" } } } } Test#%d { "my" : { "hello" : "world" } } object(MyArrayObject)#%d (1) { [%s]=> array(1) { ["my"]=> object(MyArrayObject)#%d (1) { [%s]=> array(1) { ["hello"]=> string(5) "world" } } } } Test#%d { "my" : [ [ "hello", "world" ] ] } object(MyArrayObject)#%d (1) { [%s]=> array(1) { ["my"]=> object(MyArrayObject)#%d (1) { [%s]=> array(1) { [0]=> object(MyArrayObject)#%d (1) { [%s]=> array(2) { [0]=> string(5) "hello" [1]=> string(5) "world" } } } } } } Test#%d { "my" : { "0" : [ "hello", "world" ] } } object(MyArrayObject)#%d (1) { [%s]=> array(1) { ["my"]=> object(MyArrayObject)#%d (1) { [%s]=> array(1) { [0]=> object(MyArrayObject)#%d (1) { [%s]=> array(2) { [0]=> string(5) "hello" [1]=> string(5) "world" } } } } } } ===DONE=== mongodb-1.1.5/tests/bson/bson-encode-001.phpt0000664000175000017500000001711012673034026020500 0ustar jmikolajmikola--TEST-- BSON encoding: Encoding data into BSON representation, and BSON into Extended JSON --SKIPIF-- --FILE-- "world"), (object)array("hello" => "world"), array(array("hello" => "world")), array((object)array("hello" => "world")), array(array(1, 2, 3, 4, 5, 6, 7, 8, 9)), array((object)array(1, 2, 3, 4, 5, 6, 7, 8, 9)), array(array("0" => 1, "1" => 2, "2" => 3, "3" => 4, "4" => 5, "5" => 6, "6" => 7, "7" => 8, "8" => 9)), array(null), array(123), array(4.23), array(true), array(false), array("string"), array("string", true), array('test', 'foo', 'bar'), array('test' => 'test', 'foo' => 'foo', 'bar' => 'bar'), array('foo' => 'test', 'foo', 'bar'), array("int" => 3, "boolean" => true, "array" => array("foo", "bar"), "object" => new stdclass, "string" => "test", 3 => "test"), array(array("string", true)), array(array('test', 'foo', 'bar')), array(array('test' => 'test', 'foo' => 'foo', 'bar' => 'bar')), array(array('foo' => 'test', 'foo', 'bar')), array(array("int" => 3, "boolean" => true, "array" => array("foo", "bar"), "object" => new stdclass, "string" => "test", 3 => "test")), ); foreach($tests as $n => $test) { $s = fromPHP($test); echo "Test#{$n} ", toJSON($s), "\n"; hex_dump($s); } ?> ===DONE=== --EXPECT-- Test#0 { "hello" : "world" } 0 : 16 00 00 00 02 68 65 6c 6c 6f 00 06 00 00 00 77 [.....hello.....w] 10 : 6f 72 6c 64 00 00 [orld..] Test#1 { "hello" : "world" } 0 : 16 00 00 00 02 68 65 6c 6c 6f 00 06 00 00 00 77 [.....hello.....w] 10 : 6f 72 6c 64 00 00 [orld..] Test#2 { "0" : { "hello" : "world" } } 0 : 1e 00 00 00 03 30 00 16 00 00 00 02 68 65 6c 6c [.....0......hell] 10 : 6f 00 06 00 00 00 77 6f 72 6c 64 00 00 00 [o.....world...] Test#3 { "0" : { "hello" : "world" } } 0 : 1e 00 00 00 03 30 00 16 00 00 00 02 68 65 6c 6c [.....0......hell] 10 : 6f 00 06 00 00 00 77 6f 72 6c 64 00 00 00 [o.....world...] Test#4 { "0" : [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ] } 0 : 4c 00 00 00 04 30 00 44 00 00 00 10 30 00 01 00 [L....0.D....0...] 10 : 00 00 10 31 00 02 00 00 00 10 32 00 03 00 00 00 [...1......2.....] 20 : 10 33 00 04 00 00 00 10 34 00 05 00 00 00 10 35 [.3......4......5] 30 : 00 06 00 00 00 10 36 00 07 00 00 00 10 37 00 08 [......6......7..] 40 : 00 00 00 10 38 00 09 00 00 00 00 00 [....8.......] Test#5 { "0" : { "0" : 1, "1" : 2, "2" : 3, "3" : 4, "4" : 5, "5" : 6, "6" : 7, "7" : 8, "8" : 9 } } 0 : 4c 00 00 00 03 30 00 44 00 00 00 10 30 00 01 00 [L....0.D....0...] 10 : 00 00 10 31 00 02 00 00 00 10 32 00 03 00 00 00 [...1......2.....] 20 : 10 33 00 04 00 00 00 10 34 00 05 00 00 00 10 35 [.3......4......5] 30 : 00 06 00 00 00 10 36 00 07 00 00 00 10 37 00 08 [......6......7..] 40 : 00 00 00 10 38 00 09 00 00 00 00 00 [....8.......] Test#6 { "0" : [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ] } 0 : 4c 00 00 00 04 30 00 44 00 00 00 10 30 00 01 00 [L....0.D....0...] 10 : 00 00 10 31 00 02 00 00 00 10 32 00 03 00 00 00 [...1......2.....] 20 : 10 33 00 04 00 00 00 10 34 00 05 00 00 00 10 35 [.3......4......5] 30 : 00 06 00 00 00 10 36 00 07 00 00 00 10 37 00 08 [......6......7..] 40 : 00 00 00 10 38 00 09 00 00 00 00 00 [....8.......] Test#7 { "0" : null } 0 : 08 00 00 00 0a 30 00 00 [.....0..] Test#8 { "0" : 123 } 0 : 0c 00 00 00 10 30 00 7b 00 00 00 00 [.....0.{....] Test#9 { "0" : 4.23 } 0 : 10 00 00 00 01 30 00 ec 51 b8 1e 85 eb 10 40 00 [.....0..Q.....@.] Test#10 { "0" : true } 0 : 09 00 00 00 08 30 00 01 00 [.....0...] Test#11 { "0" : false } 0 : 09 00 00 00 08 30 00 00 00 [.....0...] Test#12 { "0" : "string" } 0 : 13 00 00 00 02 30 00 07 00 00 00 73 74 72 69 6e [.....0.....strin] 10 : 67 00 00 [g..] Test#13 { "0" : "string", "1" : true } 0 : 17 00 00 00 02 30 00 07 00 00 00 73 74 72 69 6e [.....0.....strin] 10 : 67 00 08 31 00 01 00 [g..1...] Test#14 { "0" : "test", "1" : "foo", "2" : "bar" } 0 : 27 00 00 00 02 30 00 05 00 00 00 74 65 73 74 00 ['....0.....test.] 10 : 02 31 00 04 00 00 00 66 6f 6f 00 02 32 00 04 00 [.1.....foo..2...] 20 : 00 00 62 61 72 00 00 [..bar..] Test#15 { "test" : "test", "foo" : "foo", "bar" : "bar" } 0 : 2e 00 00 00 02 74 65 73 74 00 05 00 00 00 74 65 [.....test.....te] 10 : 73 74 00 02 66 6f 6f 00 04 00 00 00 66 6f 6f 00 [st..foo.....foo.] 20 : 02 62 61 72 00 04 00 00 00 62 61 72 00 00 [.bar.....bar..] Test#16 { "foo" : "test", "0" : "foo", "1" : "bar" } 0 : 29 00 00 00 02 66 6f 6f 00 05 00 00 00 74 65 73 [)....foo.....tes] 10 : 74 00 02 30 00 04 00 00 00 66 6f 6f 00 02 31 00 [t..0.....foo..1.] 20 : 04 00 00 00 62 61 72 00 00 [....bar..] Test#17 { "int" : 3, "boolean" : true, "array" : [ "foo", "bar" ], "object" : { }, "string" : "test", "3" : "test" } 0 : 64 00 00 00 10 69 6e 74 00 03 00 00 00 08 62 6f [d....int......bo] 10 : 6f 6c 65 61 6e 00 01 04 61 72 72 61 79 00 1b 00 [olean...array...] 20 : 00 00 02 30 00 04 00 00 00 66 6f 6f 00 02 31 00 [...0.....foo..1.] 30 : 04 00 00 00 62 61 72 00 00 03 6f 62 6a 65 63 74 [....bar...object] 40 : 00 05 00 00 00 00 02 73 74 72 69 6e 67 00 05 00 [.......string...] 50 : 00 00 74 65 73 74 00 02 33 00 05 00 00 00 74 65 [..test..3.....te] 60 : 73 74 00 00 [st..] Test#18 { "0" : [ "string", true ] } 0 : 1f 00 00 00 04 30 00 17 00 00 00 02 30 00 07 00 [.....0......0...] 10 : 00 00 73 74 72 69 6e 67 00 08 31 00 01 00 00 [..string..1....] Test#19 { "0" : [ "test", "foo", "bar" ] } 0 : 2f 00 00 00 04 30 00 27 00 00 00 02 30 00 05 00 [/....0.'....0...] 10 : 00 00 74 65 73 74 00 02 31 00 04 00 00 00 66 6f [..test..1.....fo] 20 : 6f 00 02 32 00 04 00 00 00 62 61 72 00 00 00 [o..2.....bar...] Test#20 { "0" : { "test" : "test", "foo" : "foo", "bar" : "bar" } } 0 : 36 00 00 00 03 30 00 2e 00 00 00 02 74 65 73 74 [6....0......test] 10 : 00 05 00 00 00 74 65 73 74 00 02 66 6f 6f 00 04 [.....test..foo..] 20 : 00 00 00 66 6f 6f 00 02 62 61 72 00 04 00 00 00 [...foo..bar.....] 30 : 62 61 72 00 00 00 [bar...] Test#21 { "0" : { "foo" : "test", "0" : "foo", "1" : "bar" } } 0 : 31 00 00 00 03 30 00 29 00 00 00 02 66 6f 6f 00 [1....0.)....foo.] 10 : 05 00 00 00 74 65 73 74 00 02 30 00 04 00 00 00 [....test..0.....] 20 : 66 6f 6f 00 02 31 00 04 00 00 00 62 61 72 00 00 [foo..1.....bar..] 30 : 00 [.] Test#22 { "0" : { "int" : 3, "boolean" : true, "array" : [ "foo", "bar" ], "object" : { }, "string" : "test", "3" : "test" } } 0 : 6c 00 00 00 03 30 00 64 00 00 00 10 69 6e 74 00 [l....0.d....int.] 10 : 03 00 00 00 08 62 6f 6f 6c 65 61 6e 00 01 04 61 [.....boolean...a] 20 : 72 72 61 79 00 1b 00 00 00 02 30 00 04 00 00 00 [rray......0.....] 30 : 66 6f 6f 00 02 31 00 04 00 00 00 62 61 72 00 00 [foo..1.....bar..] 40 : 03 6f 62 6a 65 63 74 00 05 00 00 00 00 02 73 74 [.object.......st] 50 : 72 69 6e 67 00 05 00 00 00 74 65 73 74 00 02 33 [ring.....test..3] 60 : 00 05 00 00 00 74 65 73 74 00 00 00 [.....test...] ===DONE=== mongodb-1.1.5/tests/bson/bson-encode-002.phpt0000664000175000017500000000743612673034026020513 0ustar jmikolajmikola--TEST-- BSON encoding: Encoding objects into BSON representation --SKIPIF-- --FILE-- "class", "data"); } public function bsonUnserialize(array $data) { echo __METHOD__, "() was called with data:\n"; var_dump($data); } } class NumericArray implements BSON\Serializable, BSON\Unserializable { public function bsonSerialize() { return array(1, 2, 3); } public function bsonUnserialize(array $data) { echo __METHOD__, "() was called with data:\n"; var_dump($data); } } echo "Testing top-level AssociativeArray:\n"; $bson = fromPHP(new AssociativeArray); echo toJSON($bson), "\n"; echo "Encoded BSON:\n"; hex_dump($bson); $value = toPHP($bson, array("root" => 'AssociativeArray')); echo "Decoded BSON:\n"; var_dump($value); echo "\nTesting embedded AssociativeArray:\n"; $bson = fromPHP(array('embed' => new AssociativeArray)); echo toJSON($bson), "\n"; echo "Encoded BSON:\n"; hex_dump($bson); $value = toPHP($bson, array("document" => 'AssociativeArray')); echo "Decoded BSON:\n"; var_dump($value); echo "\nTesting top-level NumericArray:\n"; $bson = fromPHP(new NumericArray); echo toJSON($bson), "\n"; echo "Encoded BSON:\n"; hex_dump($bson); $value = toPHP($bson, array("root" => 'NumericArray')); echo "Decoded BSON:\n"; var_dump($value); echo "\nTesting embedded NumericArray:\n"; $bson = fromPHP(array('embed' => new NumericArray)); echo toJSON($bson), "\n"; echo "Encoded BSON:\n"; hex_dump($bson); $value = toPHP($bson, array("array" => 'NumericArray')); echo "Decoded BSON:\n"; var_dump($value); ?> ===DONE=== --EXPECTF-- Testing top-level AssociativeArray: { "random" : "class", "0" : "data" } Encoded BSON: 0 : 23 00 00 00 02 72 61 6e 64 6f 6d 00 06 00 00 00 [#....random.....] 10 : 63 6c 61 73 73 00 02 30 00 05 00 00 00 64 61 74 [class..0.....dat] 20 : 61 00 00 [a..] AssociativeArray::bsonUnserialize() was called with data: array(2) { ["random"]=> string(5) "class" [0]=> string(4) "data" } Decoded BSON: object(AssociativeArray)#%d (0) { } Testing embedded AssociativeArray: { "embed" : { "random" : "class", "0" : "data" } } Encoded BSON: 0 : 2f 00 00 00 03 65 6d 62 65 64 00 23 00 00 00 02 [/....embed.#....] 10 : 72 61 6e 64 6f 6d 00 06 00 00 00 63 6c 61 73 73 [random.....class] 20 : 00 02 30 00 05 00 00 00 64 61 74 61 00 00 00 [..0.....data...] AssociativeArray::bsonUnserialize() was called with data: array(2) { ["random"]=> string(5) "class" [0]=> string(4) "data" } Decoded BSON: object(stdClass)#%d (1) { ["embed"]=> object(AssociativeArray)#%d (0) { } } Testing top-level NumericArray: { "0" : 1, "1" : 2, "2" : 3 } Encoded BSON: 0 : 1a 00 00 00 10 30 00 01 00 00 00 10 31 00 02 00 [.....0......1...] 10 : 00 00 10 32 00 03 00 00 00 00 [...2......] NumericArray::bsonUnserialize() was called with data: array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) } Decoded BSON: object(NumericArray)#%d (0) { } Testing embedded NumericArray: { "embed" : [ 1, 2, 3 ] } Encoded BSON: 0 : 26 00 00 00 04 65 6d 62 65 64 00 1a 00 00 00 10 [&....embed......] 10 : 30 00 01 00 00 00 10 31 00 02 00 00 00 10 32 00 [0......1......2.] 20 : 03 00 00 00 00 00 [......] NumericArray::bsonUnserialize() was called with data: array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) } Decoded BSON: object(stdClass)#%d (1) { ["embed"]=> object(NumericArray)#%d (0) { } } ===DONE=== mongodb-1.1.5/tests/bson/bson-encode-003.phpt0000664000175000017500000001037112673034026020504 0ustar jmikolajmikola--TEST-- BSON encoding: Encoding objects into BSON representation --SKIPIF-- --FILE-- "class", "data" ); } function bsonUnserialize(array $data) { $this->props = $data; } } class MyClass2 implements BSON\Persistable { function bsonSerialize() { return array( 1, 2, 3, ); } function bsonUnserialize(array $data) { $this->props = $data; } } $tests = array( array("stuff" => new MyClass), array("stuff" => new MyClass2), array("stuff" => array(new MyClass, new MyClass2)), ); foreach($tests as $n => $test) { $s = fromPHP($test); echo "Test#{$n} ", toJSON($s), "\n"; hex_dump($s); $ret = toPHP($s); var_dump($ret); } ?> ===DONE=== --EXPECTF-- Test#0 { "stuff" : { "__pclass" : { "$type" : "80", "$binary" : "TXlDbGFzcw==" }, "random" : "class", "0" : "data" } } 0 : 45 00 00 00 03 73 74 75 66 66 00 39 00 00 00 05 [E....stuff.9....] 10 : 5f 5f 70 63 6c 61 73 73 00 07 00 00 00 80 4d 79 [__pclass......My] 20 : 43 6c 61 73 73 02 72 61 6e 64 6f 6d 00 06 00 00 [Class.random....] 30 : 00 63 6c 61 73 73 00 02 30 00 05 00 00 00 64 61 [.class..0.....da] 40 : 74 61 00 00 00 [ta...] object(stdClass)#%d (1) { ["stuff"]=> object(MyClass)#%d (1) { ["props"]=> array(3) { ["__pclass"]=> object(%SBSON\Binary)#%d (2) { ["data"]=> string(7) "MyClass" ["type"]=> int(128) } ["random"]=> string(5) "class" [0]=> string(4) "data" } } } Test#1 { "stuff" : { "__pclass" : { "$type" : "80", "$binary" : "TXlDbGFzczI=" }, "0" : 1, "1" : 2, "2" : 3 } } 0 : 3d 00 00 00 03 73 74 75 66 66 00 31 00 00 00 05 [=....stuff.1....] 10 : 5f 5f 70 63 6c 61 73 73 00 08 00 00 00 80 4d 79 [__pclass......My] 20 : 43 6c 61 73 73 32 10 30 00 01 00 00 00 10 31 00 [Class2.0......1.] 30 : 02 00 00 00 10 32 00 03 00 00 00 00 00 [.....2.......] object(stdClass)#%d (1) { ["stuff"]=> object(MyClass2)#%d (1) { ["props"]=> array(4) { ["__pclass"]=> object(%SBSON\Binary)#%d (2) { ["data"]=> string(8) "MyClass2" ["type"]=> int(128) } [0]=> int(1) [1]=> int(2) [2]=> int(3) } } } Test#2 { "stuff" : [ { "__pclass" : { "$type" : "80", "$binary" : "TXlDbGFzcw==" }, "random" : "class", "0" : "data" }, { "__pclass" : { "$type" : "80", "$binary" : "TXlDbGFzczI=" }, "0" : 1, "1" : 2, "2" : 3 } ] } 0 : 81 00 00 00 04 73 74 75 66 66 00 75 00 00 00 03 [.....stuff.u....] 10 : 30 00 39 00 00 00 05 5f 5f 70 63 6c 61 73 73 00 [0.9....__pclass.] 20 : 07 00 00 00 80 4d 79 43 6c 61 73 73 02 72 61 6e [.....MyClass.ran] 30 : 64 6f 6d 00 06 00 00 00 63 6c 61 73 73 00 02 30 [dom.....class..0] 40 : 00 05 00 00 00 64 61 74 61 00 00 03 31 00 31 00 [.....data...1.1.] 50 : 00 00 05 5f 5f 70 63 6c 61 73 73 00 08 00 00 00 [...__pclass.....] 60 : 80 4d 79 43 6c 61 73 73 32 10 30 00 01 00 00 00 [.MyClass2.0.....] 70 : 10 31 00 02 00 00 00 10 32 00 03 00 00 00 00 00 [.1......2.......] 80 : 00 [.] object(stdClass)#%d (1) { ["stuff"]=> array(2) { [0]=> object(MyClass)#%d (1) { ["props"]=> array(3) { ["__pclass"]=> object(%SBSON\Binary)#%d (2) { ["data"]=> string(7) "MyClass" ["type"]=> int(128) } ["random"]=> string(5) "class" [0]=> string(4) "data" } } [1]=> object(MyClass2)#%d (1) { ["props"]=> array(4) { ["__pclass"]=> object(%SBSON\Binary)#%d (2) { ["data"]=> string(8) "MyClass2" ["type"]=> int(128) } [0]=> int(1) [1]=> int(2) [2]=> int(3) } } } } ===DONE=== mongodb-1.1.5/tests/bson/bson-encode-004.phpt0000664000175000017500000001065412673034026020511 0ustar jmikolajmikola--TEST-- BSON encoding: Object Document Mapper --SKIPIF-- --FILE-- addAddress($sunnyvale); $hannes->addAddress($kopavogur); $mikola = new Person("Jeremy", 21); $michigan = new Address(48169, "USA"); $hannes->addFriend($mikola); var_dump($hannes); $s = fromPHP(array($hannes)); echo "Test ", toJSON($s), "\n"; hex_dump($s); $ret = toPHP($s); var_dump($ret); ?> ===DONE=== --EXPECTF-- object(Person)#%d (5) { ["name":protected]=> string(6) "Hannes" ["age":protected]=> int(42) ["addresses":protected]=> array(2) { [0]=> object(Address)#%d (2) { ["zip":protected]=> int(94086) ["country":protected]=> string(3) "USA" } [1]=> object(Address)#%d (2) { ["zip":protected]=> int(200) ["country":protected]=> string(7) "Iceland" } } ["friends":protected]=> array(1) { [0]=> object(Person)#%d (5) { ["name":protected]=> string(6) "Jeremy" ["age":protected]=> int(21) ["addresses":protected]=> array(0) { } ["friends":protected]=> array(0) { } ["secret":protected]=> string(24) "Jeremy confidential info" } } ["secret":protected]=> string(24) "Hannes confidential info" } Test { "0" : { "__pclass" : { "$type" : "80", "$binary" : "UGVyc29u" }, "name" : "Hannes", "age" : 42, "addresses" : [ { "__pclass" : { "$type" : "80", "$binary" : "QWRkcmVzcw==" }, "zip" : 94086, "country" : "USA" }, { "__pclass" : { "$type" : "80", "$binary" : "QWRkcmVzcw==" }, "zip" : 200, "country" : "Iceland" } ], "friends" : [ { "__pclass" : { "$type" : "80", "$binary" : "UGVyc29u" }, "name" : "Jeremy", "age" : 21, "addresses" : [ ], "friends" : [ ] } ] } } 0 : 23 01 00 00 03 30 00 1b 01 00 00 05 5f 5f 70 63 [#....0......__pc] 10 : 6c 61 73 73 00 06 00 00 00 80 50 65 72 73 6f 6e [lass......Person] 20 : 02 6e 61 6d 65 00 07 00 00 00 48 61 6e 6e 65 73 [.name.....Hannes] 30 : 00 10 61 67 65 00 2a 00 00 00 04 61 64 64 72 65 [..age.*....addre] 40 : 73 73 65 73 00 79 00 00 00 03 30 00 35 00 00 00 [sses.y....0.5...] 50 : 05 5f 5f 70 63 6c 61 73 73 00 07 00 00 00 80 41 [.__pclass......A] 60 : 64 64 72 65 73 73 10 7a 69 70 00 86 6f 01 00 02 [ddress.zip..o...] 70 : 63 6f 75 6e 74 72 79 00 04 00 00 00 55 53 41 00 [country.....USA.] 80 : 00 03 31 00 39 00 00 00 05 5f 5f 70 63 6c 61 73 [..1.9....__pclas] 90 : 73 00 07 00 00 00 80 41 64 64 72 65 73 73 10 7a [s......Address.z] A0 : 69 70 00 c8 00 00 00 02 63 6f 75 6e 74 72 79 00 [ip......country.] B0 : 08 00 00 00 49 63 65 6c 61 6e 64 00 00 00 04 66 [....Iceland....f] C0 : 72 69 65 6e 64 73 00 5a 00 00 00 03 30 00 52 00 [riends.Z....0.R.] D0 : 00 00 05 5f 5f 70 63 6c 61 73 73 00 06 00 00 00 [...__pclass.....] E0 : 80 50 65 72 73 6f 6e 02 6e 61 6d 65 00 07 00 00 [.Person.name....] F0 : 00 4a 65 72 65 6d 79 00 10 61 67 65 00 15 00 00 [.Jeremy..age....] 100 : 00 04 61 64 64 72 65 73 73 65 73 00 05 00 00 00 [..addresses.....] 110 : 00 04 66 72 69 65 6e 64 73 00 05 00 00 00 00 00 [..friends.......] 120 : 00 00 00 [...] object(stdClass)#%d (1) { [0]=> object(Person)#%d (5) { ["name":protected]=> string(6) "Hannes" ["age":protected]=> int(42) ["addresses":protected]=> array(2) { [0]=> object(Address)#%d (2) { ["zip":protected]=> int(94086) ["country":protected]=> string(3) "USA" } [1]=> object(Address)#%d (2) { ["zip":protected]=> int(200) ["country":protected]=> string(7) "Iceland" } } ["friends":protected]=> array(1) { [0]=> object(Person)#%d (5) { ["name":protected]=> string(6) "Jeremy" ["age":protected]=> int(21) ["addresses":protected]=> array(0) { } ["friends":protected]=> array(0) { } ["secret":protected]=> string(4) "none" } } ["secret":protected]=> string(4) "none" } } ===DONE=== mongodb-1.1.5/tests/bson/bson-encode-005.phpt0000664000175000017500000000147312673034026020511 0ustar jmikolajmikola--TEST-- BSON encoding: Object Document Mapper --SKIPIF-- --FILE-- array(), "emptyclass" => new stdclass, ); $s = fromPHP($data); echo "Test ", toJSON($s), "\n"; hex_dump($s); $ret = toPHP($s); var_dump($ret); ?> ===DONE=== --EXPECTF-- Test { "emptyarray" : [ ], "emptyclass" : { } } 0 : 27 00 00 00 04 65 6d 70 74 79 61 72 72 61 79 00 ['....emptyarray.] 10 : 05 00 00 00 00 03 65 6d 70 74 79 63 6c 61 73 73 [......emptyclass] 20 : 00 05 00 00 00 00 00 [.......] object(stdClass)#%d (2) { ["emptyarray"]=> array(0) { } ["emptyclass"]=> object(stdClass)#%d (0) { } } ===DONE=== mongodb-1.1.5/tests/bson/bson-fromJSON-001.phpt0000664000175000017500000000211412673034026020676 0ustar jmikolajmikola--TEST-- BSON\fromJSON(): Decoding JSON --SKIPIF-- --FILE-- ===DONE=== --EXPECT-- Test {} 0 : 05 00 00 00 00 [.....] Test { "foo": "bar" } 0 : 12 00 00 00 02 66 6f 6f 00 04 00 00 00 62 61 72 [.....foo.....bar] 10 : 00 00 [..] Test { "foo": [ 1, 2, 3 ]} 0 : 24 00 00 00 04 66 6f 6f 00 1a 00 00 00 10 30 00 [$....foo......0.] 10 : 01 00 00 00 10 31 00 02 00 00 00 10 32 00 03 00 [.....1......2...] 20 : 00 00 00 00 [....] Test { "foo": { "bar": 1 }} 0 : 18 00 00 00 03 66 6f 6f 00 0e 00 00 00 10 62 61 [.....foo......ba] 10 : 72 00 01 00 00 00 00 00 [r.......] ===DONE=== mongodb-1.1.5/tests/bson/bson-fromJSON-002.phpt0000664000175000017500000000444212673034026020705 0ustar jmikolajmikola--TEST-- BSON\fromJSON(): Decoding extended JSON types --SKIPIF-- --FILE-- ===DONE=== --EXPECT-- Test { "_id": { "$oid": "56315a7c6118fd1b920270b1" }} 0 : 16 00 00 00 07 5f 69 64 00 56 31 5a 7c 61 18 fd [....._id.V1Z|a..] 10 : 1b 92 02 70 b1 00 [...p..] Test { "binary": { "$binary": "Zm9v", "$type": "00" }} 0 : 15 00 00 00 05 62 69 6e 61 72 79 00 03 00 00 00 [.....binary.....] 10 : 00 66 6f 6f 00 [.foo.] Test { "date": { "$date": "2015-10-28T00:00:00Z" }} 0 : 13 00 00 00 09 64 61 74 65 00 00 80 be ab 50 01 [.....date.....P.] 10 : 00 00 00 [...] Test { "timestamp": { "$timestamp": { "t": 1446084619, "i": 0 }}} 0 : 18 00 00 00 11 74 69 6d 65 73 74 61 6d 70 00 00 [.....timestamp..] 10 : 00 00 00 0b 80 31 56 00 [.....1V.] Test { "regex": { "$regex": "pattern", "$options": "i" }} 0 : 16 00 00 00 0b 72 65 67 65 78 00 70 61 74 74 65 [.....regex.patte] 10 : 72 6e 00 69 00 00 [rn.i..] Test { "undef": { "$undefined": true }} 0 : 0c 00 00 00 06 75 6e 64 65 66 00 00 [.....undef..] Test { "minkey": { "$minKey": 1 }} 0 : 0d 00 00 00 ff 6d 69 6e 6b 65 79 00 00 [.....minkey..] Test { "maxkey": { "$maxKey": 1 }} 0 : 0d 00 00 00 7f 6d 61 78 6b 65 79 00 00 [.....maxkey..] Test { "long": { "$numberLong": "1234" }} 0 : 13 00 00 00 12 6c 6f 6e 67 00 d2 04 00 00 00 00 [.....long.......] 10 : 00 00 00 [...] ===DONE=== mongodb-1.1.5/tests/bson/bson-fromJSON_error-001.phpt0000664000175000017500000000101012673034026022101 0ustar jmikolajmikola--TEST-- BSON\fromJSON(): invalid JSON --SKIPIF-- --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException lexical error: invalid string in json text. foo (right here) ------^ ===DONE=== mongodb-1.1.5/tests/bson/bson-fromPHP-001.phpt0000664000175000017500000000266412673034026020566 0ustar jmikolajmikola--TEST-- BSON\fromPHP(): bsonSerialize() allows array and stdClass --SKIPIF-- --FILE-- data = $data; } public function bsonSerialize() { return $this->data; } } $tests = array( array(1, 2, 3), array('foo' => 'bar'), (object) array(1, 2, 3), (object) array('foo' => 'bar'), ); echo "Testing top-level objects\n"; foreach ($tests as $test) { try { echo toJson(fromPHP(new MyDocument($test))), "\n"; } catch (MongoDB\Driver\Exception\UnexpectedValueException $e) { echo $e->getMessage(), "\n"; } } echo "\nTesting nested objects\n"; foreach ($tests as $test) { try { echo toJson(fromPHP(new MyDocument(array('nested' => new MyDocument($test))))), "\n"; } catch (MongoDB\Driver\Exception\UnexpectedValueException $e) { echo $e->getMessage(), "\n"; } } ?> ===DONE=== --EXPECTF-- Testing top-level objects { "0" : 1, "1" : 2, "2" : 3 } { "foo" : "bar" } { "0" : 1, "1" : 2, "2" : 3 } { "foo" : "bar" } Testing nested objects { "nested" : [ 1, 2, 3 ] } { "nested" : { "foo" : "bar" } } { "nested" : { "0" : 1, "1" : 2, "2" : 3 } } { "nested" : { "foo" : "bar" } } ===DONE=== mongodb-1.1.5/tests/bson/bson-fromPHP-002.phpt0000664000175000017500000000110712673034026020556 0ustar jmikolajmikola--TEST-- BSON\fromPHP(): Encoding non-Persistable objects as a document --INI-- date.timezone=America/Los_Angeles --SKIPIF-- --FILE-- ===DONE=== --EXPECT-- Test { "baz" : 3 } 0 : 0e 00 00 00 10 62 61 7a 00 03 00 00 00 00 [.....baz......] ===DONE=== mongodb-1.1.5/tests/bson/bson-fromPHP-003.phpt0000664000175000017500000000244412673034026020564 0ustar jmikolajmikola--TEST-- BSON\fromPHP(): Encoding non-Persistable objects as a document field value --INI-- date.timezone=America/Los_Angeles --SKIPIF-- --FILE-- new BSON\UTCDateTime('1416445411987')), array(new MyDocument), array('x' => new MyDocument), ); foreach ($tests as $document) { $s = fromPHP($document); echo "Test ", toJSON($s), "\n"; hex_dump($s); } ?> ===DONE=== --EXPECT-- Test { "0" : { "$date" : 1416445411987 } } 0 : 10 00 00 00 09 30 00 93 c2 b9 ca 49 01 00 00 00 [.....0.....I....] Test { "x" : { "$date" : 1416445411987 } } 0 : 10 00 00 00 09 78 00 93 c2 b9 ca 49 01 00 00 00 [.....x.....I....] Test { "0" : { "baz" : 3 } } 0 : 16 00 00 00 03 30 00 0e 00 00 00 10 62 61 7a 00 [.....0......baz.] 10 : 03 00 00 00 00 00 [......] Test { "x" : { "baz" : 3 } } 0 : 16 00 00 00 03 78 00 0e 00 00 00 10 62 61 7a 00 [.....x......baz.] 10 : 03 00 00 00 00 00 [......] ===DONE=== mongodb-1.1.5/tests/bson/bson-fromPHP_error-001.phpt0000664000175000017500000000377612673034026022004 0ustar jmikolajmikola--TEST-- BSON\fromPHP(): bsonSerialize() must return an array or stdClass --SKIPIF-- --FILE-- data = $data; } public function bsonSerialize() { return $this->data; } } $invalidValues = array(null, 123, 'foo', true, new MyDocument); echo "Testing top-level objects\n"; foreach ($invalidValues as $invalidValue) { try { hex_dump(fromPHP(new MyDocument($invalidValue))); } catch (MongoDB\Driver\Exception\UnexpectedValueException $e) { echo $e->getMessage(), "\n"; } } echo "\nTesting nested objects\n"; foreach ($invalidValues as $invalidValue) { try { hex_dump(fromPHP(new MyDocument(array('nested' => new MyDocument($invalidValue))))); } catch (MongoDB\Driver\Exception\UnexpectedValueException $e) { echo $e->getMessage(), "\n"; } } ?> ===DONE=== --EXPECTF-- Testing top-level objects Expected MyDocument::bsonSerialize() to return an array or stdClass, %r(null|NULL)%r given Expected MyDocument::bsonSerialize() to return an array or stdClass, integer given Expected MyDocument::bsonSerialize() to return an array or stdClass, string given Expected MyDocument::bsonSerialize() to return an array or stdClass, boolean given Expected MyDocument::bsonSerialize() to return an array or stdClass, MyDocument given Testing nested objects Expected MyDocument::bsonSerialize() to return an array or stdClass, %r(null|NULL)%r given Expected MyDocument::bsonSerialize() to return an array or stdClass, integer given Expected MyDocument::bsonSerialize() to return an array or stdClass, string given Expected MyDocument::bsonSerialize() to return an array or stdClass, boolean given Expected MyDocument::bsonSerialize() to return an array or stdClass, MyDocument given ===DONE=== mongodb-1.1.5/tests/bson/bson-fromPHP_error-002.phpt0000664000175000017500000000144312673034026021772 0ustar jmikolajmikola--TEST--o BSON\fromPHP(): Encoding unknown Type objects as a document field value --SKIPIF-- --FILE-- new UnknownType()), ); foreach ($tests as $document) { echo throws(function() use ($document) { fromPHP($document); }, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n"; } ?> ===DONE=== --EXPECTF-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException Unexpected %SBSON\Type instance: UnknownType OK: Got MongoDB\Driver\Exception\UnexpectedValueException Unexpected %SBSON\Type instance: UnknownType ===DONE=== mongodb-1.1.5/tests/bson/bson-fromPHP_error-003.phpt0000664000175000017500000000413012673034026021767 0ustar jmikolajmikola--TEST-- BSON\fromPHP(): Encoding non-Serializable Type objects as a root element --INI-- date.timezone=America/Los_Angeles --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException %S\BSON\Type instance UnknownType cannot be serialized as a root element OK: Got MongoDB\Driver\Exception\UnexpectedValueException %S\BSON\Type instance %S\BSON\Binary cannot be serialized as a root element OK: Got MongoDB\Driver\Exception\UnexpectedValueException %S\BSON\Type instance %S\BSON\Javascript cannot be serialized as a root element OK: Got MongoDB\Driver\Exception\UnexpectedValueException %S\BSON\Type instance %S\BSON\MinKey cannot be serialized as a root element OK: Got MongoDB\Driver\Exception\UnexpectedValueException %S\BSON\Type instance %S\BSON\MaxKey cannot be serialized as a root element OK: Got MongoDB\Driver\Exception\UnexpectedValueException %S\BSON\Type instance %S\BSON\ObjectID cannot be serialized as a root element OK: Got MongoDB\Driver\Exception\UnexpectedValueException %S\BSON\Type instance %S\BSON\Regex cannot be serialized as a root element OK: Got MongoDB\Driver\Exception\UnexpectedValueException %S\BSON\Type instance %S\BSON\Timestamp cannot be serialized as a root element OK: Got MongoDB\Driver\Exception\UnexpectedValueException %S\BSON\Type instance %S\BSON\UTCDateTime cannot be serialized as a root element ===DONE=== mongodb-1.1.5/tests/bson/bson-generate-document-id.phpt0000664000175000017500000000267712673034026022761 0ustar jmikolajmikola--TEST-- _id should only be generated for top-level document, not embedded docs --SKIPIF-- --FILE-- "bob", "address" => array( "street" => "Main St.", "city" => "New York", ), ); $bulk = new MongoDB\Driver\BulkWrite(); $user["_id"] = $bulk->insert($user); $result = $manager->executeBulkWrite(NS, $bulk); echo "Dumping inserted user document with injected _id:\n"; var_dump($user); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query(array("_id" => $user["_id"]))); echo "\nDumping fetched user document:\n"; $array = $cursor->toArray(); var_dump($array[0]); ?> ===DONE=== --EXPECTF-- Dumping inserted user document with injected _id: array(3) { ["username"]=> string(3) "bob" ["address"]=> array(2) { ["street"]=> string(8) "Main St." ["city"]=> string(8) "New York" } ["_id"]=> object(%s\ObjectID)#%d (%d) { ["oid"]=> string(24) "%s" } } Dumping fetched user document: object(stdClass)#%d (3) { ["_id"]=> object(%s\ObjectID)#%d (%d) { ["oid"]=> string(24) "%s" } ["username"]=> string(3) "bob" ["address"]=> object(stdClass)#%d (%d) { ["street"]=> string(8) "Main St." ["city"]=> string(8) "New York" } } ===DONE=== mongodb-1.1.5/tests/bson/bson-javascript-001.phpt0000664000175000017500000000146112673034026021413 0ustar jmikolajmikola--TEST-- BSON BSON\Javascript #001 --SKIPIF-- --FILE-- 42)); $tests = array( array("js" => $js), array("js" => $jswscope), ); foreach($tests as $n => $test) { echo "Test#{$n}", "\n"; $s = fromPHP($test); $testagain = toPHP($s); var_dump($test['js'] instanceof $classname); var_dump($testagain->js instanceof $classname); } ?> ===DONE=== --EXPECTF-- Test#0 bool(true) bool(true) Test#1 bool(true) bool(true) ===DONE=== mongodb-1.1.5/tests/bson/bson-javascript-002.phpt0000664000175000017500000000252612673034026021417 0ustar jmikolajmikola--TEST-- BSON BSON\Javascript debug handler --SKIPIF-- --FILE-- 42), ), array( 'function foo() { return id; }', array('id' => new $oidClassname('53e2a1c40640fd72175d4603')), ), ); foreach ($tests as $test) { list($code, $scope) = $test; $js = new $jsClassname($code, $scope); var_dump($js); } ?> ===DONE=== --EXPECTF-- object(%SBSON\Javascript)#%d (%d) { ["javascript"]=> string(33) "function foo(bar) { return bar; }" ["scope"]=> object(stdClass)#%d (%d) { } } object(%SBSON\Javascript)#%d (%d) { ["javascript"]=> string(30) "function foo() { return foo; }" ["scope"]=> object(stdClass)#%d (%d) { ["foo"]=> int(42) } } object(%SBSON\Javascript)#%d (%d) { ["javascript"]=> string(29) "function foo() { return id; }" ["scope"]=> object(stdClass)#%d (%d) { ["id"]=> object(MongoDB\BSON\ObjectID)#%d (%d) { ["oid"]=> string(24) "53e2a1c40640fd72175d4603" } } } ===DONE=== mongodb-1.1.5/tests/bson/bson-javascript_error-001.phpt0000664000175000017500000000102312673034026022616 0ustar jmikolajmikola--TEST-- BSON BSON\Javascript #001 error --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE=== mongodb-1.1.5/tests/bson/bson-javascript_error-002.phpt0000664000175000017500000000061512673034026022625 0ustar jmikolajmikola--TEST-- BSON BSON\Javascript cannot be extended --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- Fatal error: Class MyJavascript may not inherit from final class (%SBSON\Javascript) in %s on line %d mongodb-1.1.5/tests/bson/bson-javascript_error-003.phpt0000664000175000017500000000124712673034026022630 0ustar jmikolajmikola--TEST-- BSON BSON\Javascript cannot be serialized --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- OK: Got Exception Serialization of '%SBSON\Javascript' is not allowed OK: Got Exception Unserialization of '%SBSON\Javascript' is not allowed ===DONE=== mongodb-1.1.5/tests/bson/bson-maxkey-001.phpt0000664000175000017500000000136012673034026020541 0ustar jmikolajmikola--TEST-- BSON BSON\MaxKey #001 --SKIPIF-- --FILE-- $maxkey), ); foreach($tests as $n => $test) { $s = fromPHP($test); echo "Test#{$n} ", $json = toJSON($s), "\n"; $bson = fromJSON($json); $testagain = toPHP($bson); var_dump(toJSON(fromPHP($test)), toJSON(fromPHP($testagain))); var_dump((object)$test == (object)$testagain); } ?> ===DONE=== --EXPECTF-- Test#0 { "max" : { "$maxKey" : 1 } } string(29) "{ "max" : { "$maxKey" : 1 } }" string(29) "{ "max" : { "$maxKey" : 1 } }" bool(true) ===DONE=== mongodb-1.1.5/tests/bson/bson-maxkey_error-001.phpt0000664000175000017500000000057112673034026021755 0ustar jmikolajmikola--TEST-- BSON BSON\MaxKey cannot be extended --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- Fatal error: Class MyMaxKey may not inherit from final class (%SBSON\MaxKey) in %s on line %d mongodb-1.1.5/tests/bson/bson-maxkey_error-002.phpt0000664000175000017500000000120412673034026021750 0ustar jmikolajmikola--TEST-- BSON BSON\MaxKey cannot be serialized --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- OK: Got Exception Serialization of '%SBSON\MaxKey' is not allowed OK: Got Exception Unserialization of '%SBSON\MaxKey' is not allowed ===DONE=== mongodb-1.1.5/tests/bson/bson-minkey-001.phpt0000664000175000017500000000136012673034026020537 0ustar jmikolajmikola--TEST-- BSON BSON\MinKey #001 --SKIPIF-- --FILE-- $minkey), ); foreach($tests as $n => $test) { $s = fromPHP($test); echo "Test#{$n} ", $json = toJSON($s), "\n"; $bson = fromJSON($json); $testagain = toPHP($bson); var_dump(toJSON(fromPHP($test)), toJSON(fromPHP($testagain))); var_dump((object)$test == (object)$testagain); } ?> ===DONE=== --EXPECTF-- Test#0 { "min" : { "$minKey" : 1 } } string(29) "{ "min" : { "$minKey" : 1 } }" string(29) "{ "min" : { "$minKey" : 1 } }" bool(true) ===DONE=== mongodb-1.1.5/tests/bson/bson-minkey_error-001.phpt0000664000175000017500000000057112673034026021753 0ustar jmikolajmikola--TEST-- BSON BSON\MinKey cannot be extended --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- Fatal error: Class MyMinKey may not inherit from final class (%SBSON\MinKey) in %s on line %d mongodb-1.1.5/tests/bson/bson-minkey_error-002.phpt0000664000175000017500000000120412673034026021746 0ustar jmikolajmikola--TEST-- BSON BSON\MinKey cannot be serialized --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- OK: Got Exception Serialization of '%SBSON\MinKey' is not allowed OK: Got Exception Unserialization of '%SBSON\MinKey' is not allowed ===DONE=== mongodb-1.1.5/tests/bson/bson-objectid-001.phpt0000664000175000017500000000565412673034026021040 0ustar jmikolajmikola--TEST-- BSON BSON\ObjectID #001 --SKIPIF-- --FILE-- my = $sameid; $samearr = array("my" => $sameid); $std = new stdclass; $std->_id = new $classname; $array = array( "_id" => new $classname, "id" => new $classname, "d" => new $classname, ); $pregenerated = new $classname("53e28b650640fd3162152de1"); $tests = array( $array, $std, $samestd, $samearr, array("pregenerated" => $pregenerated), ); foreach($tests as $n => $test) { $s = fromPHP($test); echo "Test#{$n} ", $json = toJSON($s), "\n"; $bson = fromJSON($json); $testagain = toPHP($bson); var_dump(toJSON(fromPHP($test)), toJSON(fromPHP($testagain))); var_dump((object)$test == (object)$testagain); } throws(function() use($classname) { $id = new $classname("53e28b650640fd3162152de12"); }, "MongoDB\\Driver\\Exception\\InvalidArgumentException"); throws(function() use($classname) { $id = new $classname("53e28b650640fd3162152dg1"); }, "MongoDB\\Driver\\Exception\\InvalidArgumentException"); throws(function() use ($classname) { $id = new $classname("-3e28b650640fd3162152da1"); }, "MongoDB\\Driver\\Exception\\InvalidArgumentException"); throws(function() use($classname) { $id = new $classname(" 3e28b650640fd3162152da1"); }, "MongoDB\\Driver\\Exception\\InvalidArgumentException"); raises(function() use($pregenerated) { $pregenerated->__toString(1); }, E_WARNING); ?> ===DONE=== --EXPECTF-- Test#0 { "_id" : { "$oid" : "%s" }, "id" : { "$oid" : "%s" }, "d" : { "$oid" : "%s" } } string(146) "{ "_id" : { "$oid" : "%s" }, "id" : { "$oid" : "%s" }, "d" : { "$oid" : "%s" } }" string(146) "{ "_id" : { "$oid" : "%s" }, "id" : { "$oid" : "%s" }, "d" : { "$oid" : "%s" } }" bool(true) Test#1 { "_id" : { "$oid" : "%s" } } string(51) "{ "_id" : { "$oid" : "%s" } }" string(51) "{ "_id" : { "$oid" : "%s" } }" bool(true) Test#2 { "my" : { "$oid" : "53e2a1c40640fd72175d4603" } } string(50) "{ "my" : { "$oid" : "53e2a1c40640fd72175d4603" } }" string(50) "{ "my" : { "$oid" : "53e2a1c40640fd72175d4603" } }" bool(true) Test#3 { "my" : { "$oid" : "53e2a1c40640fd72175d4603" } } string(50) "{ "my" : { "$oid" : "53e2a1c40640fd72175d4603" } }" string(50) "{ "my" : { "$oid" : "53e2a1c40640fd72175d4603" } }" bool(true) Test#4 { "pregenerated" : { "$oid" : "53e28b650640fd3162152de1" } } string(60) "{ "pregenerated" : { "$oid" : "53e28b650640fd3162152de1" } }" string(60) "{ "pregenerated" : { "$oid" : "53e28b650640fd3162152de1" } }" bool(true) OK: Got MongoDB\Driver\Exception\InvalidArgumentException OK: Got MongoDB\Driver\Exception\InvalidArgumentException OK: Got MongoDB\Driver\Exception\InvalidArgumentException OK: Got MongoDB\Driver\Exception\InvalidArgumentException OK: Got E_WARNING ===DONE=== mongodb-1.1.5/tests/bson/bson-objectid-002.phpt0000664000175000017500000000101612673034026021025 0ustar jmikolajmikola--TEST-- BSON BSON\ObjectID #002 generates ObjectID for null or missing constructor argument --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- object(MongoDB\BSON\ObjectID)#%d (%d) { ["oid"]=> string(24) "%x" } object(MongoDB\BSON\ObjectID)#%d (%d) { ["oid"]=> string(24) "%x" } ===DONE=== mongodb-1.1.5/tests/bson/bson-objectid-003.phpt0000664000175000017500000000171712673034026021036 0ustar jmikolajmikola--TEST-- BSON BSON\ObjectID #003 construction with string argument --SKIPIF-- --FILE-- value = (string) $value; } public function __toString() { return $this->value; } } $oid = new $classname('53e2a1c40640fd72175d4603'); $str = new StringObject('53e2a1c40640fd72175d4603'); var_dump($oid); var_dump(new $classname($oid)); var_dump(new $classname($str)); ?> ===DONE=== --EXPECTF-- object(MongoDB\BSON\ObjectID)#%d (%d) { ["oid"]=> string(24) "53e2a1c40640fd72175d4603" } object(MongoDB\BSON\ObjectID)#%d (%d) { ["oid"]=> string(24) "53e2a1c40640fd72175d4603" } object(MongoDB\BSON\ObjectID)#%d (%d) { ["oid"]=> string(24) "53e2a1c40640fd72175d4603" } ===DONE=== mongodb-1.1.5/tests/bson/bson-objectid-004.phpt0000664000175000017500000000067612673034026021042 0ustar jmikolajmikola--TEST-- BSON BSON\ObjectID #004 Constructor supports uppercase hexadecimal strings --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- object(MongoDB\BSON\ObjectID)#%d (%d) { ["oid"]=> string(24) "56925b7330616224d0000001" } ===DONE=== mongodb-1.1.5/tests/bson/bson-objectid_error-001.phpt0000664000175000017500000000103612673034026022237 0ustar jmikolajmikola--TEST-- BSON BSON\ObjectID #001 error --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE=== mongodb-1.1.5/tests/bson/bson-objectid_error-002.phpt0000664000175000017500000000060312673034026022237 0ustar jmikolajmikola--TEST-- BSON BSON\ObjectID cannot be extended --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- Fatal error: Class MyObjectID may not inherit from final class (%SBSON\ObjectID) in %s on line %d mongodb-1.1.5/tests/bson/bson-objectid_error-003.phpt0000664000175000017500000000121612673034026022241 0ustar jmikolajmikola--TEST-- BSON BSON\ObjectID cannot be serialized --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- OK: Got Exception Serialization of '%SBSON\ObjectID' is not allowed OK: Got Exception Unserialization of '%SBSON\ObjectID' is not allowed ===DONE=== mongodb-1.1.5/tests/bson/bson-ods-001.phpt0000664000175000017500000001165012673034026020033 0ustar jmikolajmikola--TEST-- BSON encoding: Encoding data into BSON representation, and BSON into Extended JSON --XFAIL-- Persistable::bsonSerialize() should not return atomic modifiers (see: PHPC-550) --SKIPIF-- --FILE-- streetAddress = $streetAddress; $this->city = $city; $this->postalCode = $postalCode; } function bsonUnserialize(array $array) { foreach($array as $k => $v) { $this->{$k} = $v; } return $this; } function bsonSerialize() { return get_object_vars($this); } } class Person implements BSON\Persistable { protected $_id; protected $username; protected $email; protected $name; protected $addresses = array(); protected $_lastModified; protected $_created; function __construct($username, $email, $name) { $this->username = $username; $this->email = $email; $this->setName($name); /* Pregenerate our ObjectID */ $this->_id = new BSON\ObjectID(); } function addAddress(Address $address) { $this->addresses[] = $address; } function bsonUnserialize(array $array) { $this->__original = $array; foreach($array as $k => $v) { $this->{$k} = $v; } } function bsonSerialize() { $props = get_object_vars($this); /* If __original doesn't exist, this is a fresh object that needs to be inserted */ if (empty($this->__original)) { $props["_created"] = new BSON\UTCDateTime(microtime(true) * 1000); return $props; } /* Track the last time this person was updated */ $update = array( '$currentDate' => array( "_lastModified" => array('$type' => 'date'), ), '$set' => array(), ); /* Otherwise, only pluck out the changes so we don't have to do full object replacement */ foreach($props as $k => $v) { if (!isset($this->__original[$k])) { /* A new field -- likely a on-the-fly schema upgrade */ $updated['$set'] = array($k => $v); } } return $updated; } function getName() { return $this->name; } function setName($name) { return $this->name = $name; } } $lair77 = new Person('lair77', 'claire77@example.net', 'Claire Corwin'); $hillardhaven = new Address('4527 Kohler Square Apt. 316', 'Hillardhaven', '02622-5175'); $lair77->addAddress($hillardhaven); $prudencemouth = new Address('7042 Freida Springs', 'Prudencemouth', '94805'); $lair77->addAddress($prudencemouth); $tabitha = new Person('tabitha.mohr', 'mohr@example.org', 'Tabitha Lehner'); $konopelskichester = new Address('76650 Mina Pass', 'Konopelskichester', '69679-5471'); $tabitha->addAddress($konopelskichester); $hartmann = new Person('hartmann', 'hartmann@example.org', 'Hartmann Dedrick'); $leannefurt = new Address('151 Delbert Hills Suite 923', 'Leannefurt', '22036'); $hartmann->addAddress($leannefurt); $ena = new Person('ena', 'ena.sanford@example.net', 'Frida Sanford'); $lawsonport = new Address('3656 Jenifer Field', 'New Lawsonport', '16300'); $ena->addAddress($lawsonport); $lockman = new Person('cartwright.garland', 'lockman.olga@example.net', 'Alice Carter'); $herminia = new Address('37413 Kailee Spurs', 'East Herminia', '22107'); $lockman->addAddress($herminia); $dropcoll = new MongoDB\Driver\Command(array("drop" => COLLECTION_NAME)); $query = new MongoDB\Driver\Query(array()); $hartmannFilter = array("username" => "hartmann"); $queryHartmann = new MongoDB\Driver\Query($hartmannFilter); $bulk = new MongoDB\Driver\BulkWrite; $bulk->insert($lair77); $bulk->insert($tabitha); $bulk->insert($hartmann); $bulk->insert($ena); $bulk->insert($lockman); $m = new MongoDB\Driver\Manager(STANDALONE); try { $m->executeCommand(DATABASE_NAME, $dropcoll); } catch(Exception $e) {} $m->executeBulkWrite(NS, $bulk); foreach($m->executeQuery(NS, $query) as $person) { var_dump($person->getName()); } echo "-----\n"; $array = $m->executeQuery(NS, $queryHartmann)->toArray(); $hartmann = $array[0]; var_dump($hartmann->getName()); $hartmann->setName("Dr. " . $hartmann->getName()); $bulk = new MongoDB\Driver\BulkWrite(); $bulk->update($hartmannFilter, $hartmann); $retval = $m->executeBulkWrite(NS, $bulk); var_dump($retval->getModifiedCount()); ?> ===DONE=== --EXPECT-- string(13) "Claire Corwin" string(14) "Tabitha Lehner" string(16) "Hartmann Dedrick" string(13) "Frida Sanford" string(12) "Alice Carter" ----- string(16) "Hartmann Dedrick" int(1) ===DONE=== mongodb-1.1.5/tests/bson/bson-ods-002.phpt0000664000175000017500000001622512673034026020037 0ustar jmikolajmikola--TEST-- BSON encoding: Encoding data into BSON representation, and BSON into Extended JSON --XFAIL-- Persistable::bsonSerialize() should not return atomic modifiers (see: PHPC-550) --INI-- date.timezone=America/Los_Angeles --SKIPIF-- --FILE-- streetAddress = $streetAddress; $this->city = $city; $this->postalCode = $postalCode; } function bsonUnserialize(array $array) { foreach($array as $k => $v) { $this->{$k} = $v; } return $this; } function bsonSerialize() { return get_object_vars($this); } function getStreetAddress() { return $this->streetAddress; } } class Person implements BSON\Persistable { protected $_id; protected $username; protected $email; protected $name; protected $addresses = array(); protected $_lastModified; protected $_created; function __construct($username, $email, $name) { $this->username = $username; $this->email = $email; $this->setName($name); /* Pregenerate our ObjectID */ $this->_id = new BSON\ObjectID(); } function addAddress(Address $address) { $this->addresses[] = $address; } function bsonUnserialize(array $array) { $this->__original = $array; foreach($array as $k => $v) { $this->{$k} = $v; } } function bsonSerialize() { $props = get_object_vars($this); /* These aren't inserted/updated as values */ unset($props["__original"]); unset($props["_lastModified"]); /* If __original doesn't exist, this is a fresh object that needs to be inserted */ if (empty($this->__original)) { /* Generate the `_created` timestamp */ $props["_created"] = new BSON\UTCDateTime(microtime(true) * 1000); return $props; } /* Track the last time this person was updated */ $updated = array( '$currentDate' => array( "_lastModified" => array('$type' => "date"), ), '$set' => array(), ); /* Otherwise, only pluck out the changes so we don't have to do full object replacement */ foreach($props as $k => $v) { if (!isset($this->__original[$k])) { /* A new field -- likely a on-the-fly schema upgrade */ $updated['$set'] = array($k => $v); continue; } /* Changed value */ if ($this->__original[$k] != $v) { $updated['$set'] = array($k => $v); continue; } } return $updated; } function getName() { return $this->name; } function setName($name) { return $this->name = $name; } function getCreatedDateTime() { return $this->_created->toDateTime(); } function getLastModifiedDateTime() { return $this->_lastModified->toDateTime(); } function toArray() { $props = get_object_vars($this); unset($props["__original"]); return $props; } function getAddresses() { return $this->addresses; } } $m = new MongoDB\Driver\Manager(STANDALONE); try { /* Drop the collection between runs */ $dropcoll = new MongoDB\Driver\Command(array("drop" => COLLECTION_NAME)); $m->executeCommand(DATABASE_NAME, $dropcoll); } catch(Exception $e) {} $bulk = new MongoDB\Driver\BulkWrite; /* Claire Corwin, username: lair77 */ $lair77 = new Person("lair77", "claire77@example.net", "Claire Corwin"); $hillardhaven = new Address("4527 Kohler Square Apt. 316", "Hillardhaven", "02622-5175"); $lair77->addAddress($hillardhaven); $bulk->insert($lair77); /* Tabitha Lehner, username: tabitha.mohr */ $tabitha = new Person("tabitha.mohr", "mohr@example.org", "Tabitha Lehner"); $konopelskichester = new Address("76650 Mina Pass", "Konopelskichester", "69679-5471"); $tabitha->addAddress($konopelskichester); $bulk->insert($tabitha); /* Hartmann Dedrick, username: hartmann -- he is going to be our demo person */ $hartmann = new Person("hartmann", "hartmann@example.org", "Hartmann Dedrick"); $leannefurt = new Address("151 Delbert Hills Suite 923", "Leannefurt", "22036"); $hartmann->addAddress($leannefurt); /* He has two addresses */ $prudencemouth = new Address("7042 Freida Springs", "Prudencemouth", "94805"); $hartmann->addAddress($prudencemouth); $bulk->insert($hartmann); /* Frida Sanford, username: ena */ $ena = new Person("ena", "sanford@example.net", "Frida Sanford"); $lawsonport = new Address("3656 Jenifer Field", "New Lawsonport", "16300"); $ena->addAddress($lawsonport); $bulk->insert($ena); /* Alice Lockman, username: lockman */ $lockman = new Person("lockman", "lockman.alice@example.net", "Alice Lockman"); $herminia = new Address("37413 Kailee Spurs", "East Herminia", "22107"); $lockman->addAddress($herminia); $bulk->insert($lockman); /* Insert our fixtures in one bulk write operation */ $m->executeBulkWrite(NS, $bulk); /* Iterate over all the `examples.people`, * converting them back into Person objects -- and the nested Address object! */ $query = new MongoDB\Driver\Query(array()); foreach($m->executeQuery(NS, $query) as $person) { echo $person->getName(), " has the following address(es):\n"; foreach($person->getAddresses() as $address) { echo "\t", $address->getStreetAddress(), "\n"; } echo "\n"; } echo "-----\n"; /* Hartmann graduated with a doctorate and deserves a Dr. prefix */ $hartmannFilter = array("username" => "hartmann"); $queryHartmann = new MongoDB\Driver\Query($hartmannFilter); $array = $m->executeQuery(NS, $queryHartmann)->toArray(); $hartmann = $array[0]; $hartmann->setName("Dr. " . $hartmann->getName()); $bulk = new MongoDB\Driver\BulkWrite(); $bulk->update($hartmannFilter, $hartmann); $retval = $m->executeBulkWrite(NS, $bulk); printf("Updated %d person (%s)\n", $retval->getModifiedCount(), $hartmann->getName()); $queryAll = new MongoDB\Driver\Query(array()); $all = $m->executeQuery(NS, $queryAll)->toArray(); foreach($all as $person) { if ($person->getName() == "Dr. Hartmann Dedrick") { $array = $person->toArray(); var_dump($array["username"]); var_dump($person->getCreatedDateTime()->format(DATE_RSS)); var_dump($person->getLastModifiedDateTime()->format(DATE_RSS)); } } ?> ===DONE=== --EXPECTF-- Claire Corwin has the following address(es): 4527 Kohler Square Apt. 316 Tabitha Lehner has the following address(es): 76650 Mina Pass Hartmann Dedrick has the following address(es): 151 Delbert Hills Suite 923 7042 Freida Springs Frida Sanford has the following address(es): 3656 Jenifer Field Alice Lockman has the following address(es): 37413 Kailee Spurs ----- Updated 1 person (Dr. Hartmann Dedrick) string(8) "hartmann" string(%d) "%s" string(%d) "%s" ===DONE=== mongodb-1.1.5/tests/bson/bson-regex-001.phpt0000664000175000017500000000202512673034026020354 0ustar jmikolajmikola--TEST-- BSON BSON\Regex #001 --SKIPIF-- --FILE-- getPattern()); printf("Flags: %s\n", $regexp->getFlags()); printf("String representation: %s\n", $regexp); $tests = array( array("regex" => $regexp), ); foreach($tests as $n => $test) { $s = fromPHP($test); echo "Test#{$n} ", $json = toJSON($s), "\n"; $bson = fromJSON($json); $testagain = toPHP($bson); var_dump(toJSON(fromPHP($test)), toJSON(fromPHP($testagain))); var_dump((object)$test == (object)$testagain); } ?> ===DONE=== --EXPECTF-- Pattern: regexp Flags: i String representation: /regexp/i Test#0 { "regex" : { "$regex" : "regexp", "$options" : "i" } } string(55) "{ "regex" : { "$regex" : "regexp", "$options" : "i" } }" string(55) "{ "regex" : { "$regex" : "regexp", "$options" : "i" } }" bool(true) ===DONE=== mongodb-1.1.5/tests/bson/bson-regex-002.phpt0000664000175000017500000000064612673034026020364 0ustar jmikolajmikola--TEST-- BSON BSON\Regex debug handler --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- object(%SBSON\Regex)#%d (%d) { ["pattern"]=> string(6) "regexp" ["flags"]=> string(1) "i" } ===DONE=== mongodb-1.1.5/tests/bson/bson-regex_error-001.phpt0000664000175000017500000000144112673034026021566 0ustar jmikolajmikola--TEST-- BSON BSON\Regex #001 error --SKIPIF-- --FILE-- getPattern(true); $regexp->getFlags(true); throws(function() use($classname) { new $classname; }, "MongoDB\\Driver\\Exception\\InvalidArgumentException"); ?> ===DONE=== --EXPECTF-- Warning: %s\Regex::getPattern() expects exactly 0 parameters, 1 given in %s on line %d Warning: %s\Regex::getFlags() expects exactly 0 parameters, 1 given in %s on line %d OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE=== mongodb-1.1.5/tests/bson/bson-regex_error-002.phpt0000664000175000017500000000056412673034026021574 0ustar jmikolajmikola--TEST-- BSON BSON\Regex cannot be extended --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- Fatal error: Class MyRegex may not inherit from final class (%SBSON\Regex) in %s on line %d mongodb-1.1.5/tests/bson/bson-regex_error-003.phpt0000664000175000017500000000121412673034026021566 0ustar jmikolajmikola--TEST-- BSON BSON\Regex cannot be serialized --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- OK: Got Exception Serialization of '%SBSON\Regex' is not allowed OK: Got Exception Unserialization of '%SBSON\Regex' is not allowed ===DONE=== mongodb-1.1.5/tests/bson/bson-timestamp-001.phpt0000664000175000017500000000166112673034026021252 0ustar jmikolajmikola--TEST-- BSON BSON\Timestamp #001 --SKIPIF-- --FILE-- $timestamp), ); $s = new $classname(1234, 5678); echo $s, "\n"; foreach($tests as $n => $test) { $s = fromPHP($test); echo "Test#{$n} ", $json = toJSON($s), "\n"; $bson = fromJSON($json); $testagain = toPHP($bson); var_dump(toJSON(fromPHP($test)), toJSON(fromPHP($testagain))); var_dump((object)$test == (object)$testagain); } ?> ===DONE=== --EXPECTF-- [1234:5678] Test#0 { "timestamp" : { "$timestamp" : { "t" : 5678, "i" : 1234 } } } string(63) "{ "timestamp" : { "$timestamp" : { "t" : 5678, "i" : 1234 } } }" string(63) "{ "timestamp" : { "$timestamp" : { "t" : 5678, "i" : 1234 } } }" bool(true) ===DONE=== mongodb-1.1.5/tests/bson/bson-timestamp-002.phpt0000664000175000017500000000066012673034026021251 0ustar jmikolajmikola--TEST-- BSON BSON\Timestamp debug handler --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- object(%SBSON\Timestamp)#%d (%d) { ["increment"]=> int(1234) ["timestamp"]=> int(5678) } ===DONE=== mongodb-1.1.5/tests/bson/bson-timestamp-003.phpt0000664000175000017500000000133112673034026021246 0ustar jmikolajmikola--TEST-- BSON BSON\Timestamp constructor requires positive unsigned 32-bit integers --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- Test [2147483647:0] object(%SBSON\Timestamp)#%d (%d) { ["increment"]=> int(2147483647) ["timestamp"]=> int(0) } Test [0:2147483647] object(%SBSON\Timestamp)#%d (%d) { ["increment"]=> int(0) ["timestamp"]=> int(2147483647) } ===DONE===mongodb-1.1.5/tests/bson/bson-timestamp-004.phpt0000664000175000017500000000147312673034026021256 0ustar jmikolajmikola--TEST-- BSON BSON\Timestamp constructor requires 64-bit integers to be positive unsigned 32-bit integers --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- Test [4294967295:0] object(%SBSON\Timestamp)#%d (%d) { ["increment"]=> int(4294967295) ["timestamp"]=> int(0) } Test [0:4294967295] object(%SBSON\Timestamp)#%d (%d) { ["increment"]=> int(0) ["timestamp"]=> int(4294967295) } ===DONE=== mongodb-1.1.5/tests/bson/bson-timestamp_error-001.phpt0000664000175000017500000000102212673034026022452 0ustar jmikolajmikola--TEST-- BSON BSON\Timestamp #001 error --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE=== mongodb-1.1.5/tests/bson/bson-timestamp_error-002.phpt0000664000175000017500000000061012673034026022455 0ustar jmikolajmikola--TEST-- BSON BSON\Timestamp cannot be extended --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- Fatal error: Class MyTimestamp may not inherit from final class (%SBSON\Timestamp) in %s on line %d mongodb-1.1.5/tests/bson/bson-timestamp_error-003.phpt0000664000175000017500000000123512673034026022462 0ustar jmikolajmikola--TEST-- BSON BSON\Timestamp cannot be serialized --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- OK: Got Exception Serialization of '%SBSON\Timestamp' is not allowed OK: Got Exception Unserialization of '%SBSON\Timestamp' is not allowed ===DONE=== mongodb-1.1.5/tests/bson/bson-timestamp_error-004.phpt0000664000175000017500000000241312673034026022462 0ustar jmikolajmikola--TEST-- BSON BSON\Timestamp constructor requires positive unsigned 32-bit integers --SKIPIF-- --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected increment to be an unsigned 32-bit integer, -1 given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected increment to be an unsigned 32-bit integer, -2147483648 given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected timestamp to be an unsigned 32-bit integer, -1 given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected timestamp to be an unsigned 32-bit integer, -2147483648 given ===DONE=== mongodb-1.1.5/tests/bson/bson-timestamp_error-005.phpt0000664000175000017500000000161012673034026022461 0ustar jmikolajmikola--TEST-- BSON BSON\Timestamp constructor requires 64-bit integers to be positive unsigned 32-bit integers --SKIPIF-- --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected increment to be an unsigned 32-bit integer, 4294967296 given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected timestamp to be an unsigned 32-bit integer, 4294967296 given ===DONE=== mongodb-1.1.5/tests/bson/bson-toJSON-001.phpt0000664000175000017500000000075412673034026020365 0ustar jmikolajmikola--TEST-- BSON\toJSON(): Encoding JSON --SKIPIF-- --FILE-- 'bar' ], [ 'foo' => [ 1, 2, 3 ]], [ 'foo' => [ 'bar' => 1 ]], ]; foreach ($tests as $value) { $bson = fromPHP($value); echo toJSON($bson), "\n"; } ?> ===DONE=== --EXPECT-- { } { "foo" : "bar" } { "foo" : [ 1, 2, 3 ] } { "foo" : { "bar" : 1 } } ===DONE=== mongodb-1.1.5/tests/bson/bson-toJSON-002.phpt0000664000175000017500000000215012673034026020356 0ustar jmikolajmikola--TEST-- BSON\toJSON(): Encoding extended JSON types --SKIPIF-- --FILE-- new BSON\ObjectId('56315a7c6118fd1b920270b1')], ['binary' => new BSON\Binary('foo', BSON\Binary::TYPE_GENERIC)], ['date' => new BSON\UTCDateTime(1445990400000)], ['timestamp' => new BSON\Timestamp(BSON\Binary::TYPE_GENERIC, 1446084619)], ['regex' => new BSON\Regex('pattern', 'i')], ['minkey' => new BSON\MinKey], ['maxkey' => new BSON\MaxKey], ['long' => 1234], ]; foreach ($tests as $value) { $bson = fromPHP($value); echo toJSON($bson), "\n"; } ?> ===DONE=== --EXPECT-- { "_id" : { "$oid" : "56315a7c6118fd1b920270b1" } } { "binary" : { "$type" : "00", "$binary" : "Zm9v" } } { "date" : { "$date" : 1445990400000 } } { "timestamp" : { "$timestamp" : { "t" : 1446084619, "i" : 0 } } } { "regex" : { "$regex" : "pattern", "$options" : "i" } } { "minkey" : { "$minKey" : 1 } } { "maxkey" : { "$maxKey" : 1 } } { "long" : 1234 } ===DONE=== mongodb-1.1.5/tests/bson/bson-toJSON_error-001.phpt0000664000175000017500000000151012673034026021565 0ustar jmikolajmikola--TEST-- BSON\toJSON(): BSON decoding exceptions --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException Could not read document from BSON reader OK: Got MongoDB\Driver\Exception\UnexpectedValueException Reading document did not exhaust input buffer ===DONE=== mongodb-1.1.5/tests/bson/bson-toJSON_error-002.phpt0000664000175000017500000000140612673034026021572 0ustar jmikolajmikola--TEST-- BSON\toJSON(): BSON decoding exceptions for malformed documents --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException Could not read document from BSON reader OK: Got MongoDB\Driver\Exception\UnexpectedValueException Could not read document from BSON reader ===DONE=== mongodb-1.1.5/tests/bson/bson-toJSON_error-003.phpt0000664000175000017500000000274712673034026021604 0ustar jmikolajmikola--TEST-- BSON\toJSON(): BSON decoding exceptions for bson_as_json() failure --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException Could not convert BSON document to a JSON string OK: Got MongoDB\Driver\Exception\UnexpectedValueException Could not convert BSON document to a JSON string OK: Got MongoDB\Driver\Exception\UnexpectedValueException Could not convert BSON document to a JSON string ===DONE=== mongodb-1.1.5/tests/bson/bson-toPHP-001.phpt0000664000175000017500000000466512673034026020250 0ustar jmikolajmikola--TEST-- BSON\toPHP(): __pclass must be both instantiatable and Persistable --SKIPIF-- --FILE-- unserialized = true; } } // Create base64-encoded class names for __pclass field's binary data $bMyAbstractDocument = base64_encode('MyAbstractDocument'); $bMyDocument = base64_encode('MyDocument'); $bUnserializable = base64_encode(BSON_NAMESPACE . '\Unserializable'); $bPersistable = base64_encode(BSON_NAMESPACE . '\Persistable'); $tests = array( '{ "foo": "yes", "__pclass": { "$type" : "80", "$binary" : "' . $bMyAbstractDocument . '" } }', '{ "foo": "yes", "__pclass": { "$type" : "80", "$binary" : "' . $bMyDocument . '" } }', '{ "foo": "yes", "__pclass": { "$type" : "80", "$binary" : "' . $bUnserializable . '" } }', '{ "foo": "yes", "__pclass": { "$type" : "44", "$binary" : "' . $bPersistable . '" } }', ); foreach ($tests as $test) { echo $test, "\n"; var_dump(toPHP(fromJSON($test))); echo "\n"; } ?> ===DONE=== --EXPECTF-- { "foo": "yes", "__pclass": { "$type" : "80", "$binary" : "TXlBYnN0cmFjdERvY3VtZW50" } } object(stdClass)#%d (2) { ["foo"]=> string(3) "yes" ["__pclass"]=> object(MongoDB\BSON\Binary)#%d (2) { ["data"]=> string(18) "MyAbstractDocument" ["type"]=> int(128) } } { "foo": "yes", "__pclass": { "$type" : "80", "$binary" : "TXlEb2N1bWVudA==" } } object(stdClass)#%d (2) { ["foo"]=> string(3) "yes" ["__pclass"]=> object(MongoDB\BSON\Binary)#%d (2) { ["data"]=> string(10) "MyDocument" ["type"]=> int(128) } } { "foo": "yes", "__pclass": { "$type" : "80", "$binary" : "TW9uZ29EQlxCU09OXFVuc2VyaWFsaXphYmxl" } } object(stdClass)#%d (2) { ["foo"]=> string(3) "yes" ["__pclass"]=> object(MongoDB\BSON\Binary)#%d (2) { ["data"]=> string(27) "MongoDB\BSON\Unserializable" ["type"]=> int(128) } } { "foo": "yes", "__pclass": { "$type" : "44", "$binary" : "TW9uZ29EQlxCU09OXFBlcnNpc3RhYmxl" } } object(stdClass)#%d (2) { ["foo"]=> string(3) "yes" ["__pclass"]=> object(MongoDB\BSON\Binary)#%d (2) { ["data"]=> string(24) "MongoDB\BSON\Persistable" ["type"]=> int(68) } } ===DONE=== mongodb-1.1.5/tests/bson/bson-toPHP-002.phpt0000664000175000017500000000363212673034026020242 0ustar jmikolajmikola--TEST-- BSON\fromPHP(): Null type map values imply default behavior --SKIPIF-- --FILE-- data = array( 'list' => array(1, 2, 3), 'map' => (object) array('foo' => 'bar'), ); } public function bsonSerialize() { return $this->data; } public function bsonUnserialize(array $data) { foreach (array('list', 'map') as $key) { if (isset($data[$key])) { $this->data[$key] = $data[$key]; } } } } $bson = fromPHP(new MyDocument); echo "Test ", toJSON($bson), "\n"; hex_dump($bson); $typeMap = array( 'array' => null, 'document' => null, 'root' => null, ); var_dump(toPHP($bson, $typeMap)); ?> ===DONE=== --EXPECTF-- Test { "__pclass" : { "$type" : "80", "$binary" : "TXlEb2N1bWVudA==" }, "list" : [ 1, 2, 3 ], "map" : { "foo" : "bar" } } 0 : 55 00 00 00 05 5f 5f 70 63 6c 61 73 73 00 0a 00 [U....__pclass...] 10 : 00 00 80 4d 79 44 6f 63 75 6d 65 6e 74 04 6c 69 [...MyDocument.li] 20 : 73 74 00 1a 00 00 00 10 30 00 01 00 00 00 10 31 [st......0......1] 30 : 00 02 00 00 00 10 32 00 03 00 00 00 00 03 6d 61 [......2.......ma] 40 : 70 00 12 00 00 00 02 66 6f 6f 00 04 00 00 00 62 [p......foo.....b] 50 : 61 72 00 00 00 [ar...] object(MyDocument)#%d (1) { ["data"]=> array(2) { ["list"]=> array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) } ["map"]=> object(stdClass)#%d (1) { ["foo"]=> string(3) "bar" } } } ===DONE=== mongodb-1.1.5/tests/bson/bson-toPHP-003.phpt0000664000175000017500000002456312673034026020251 0ustar jmikolajmikola--TEST-- BSON\toPHP(): Tests from serialization specification --SKIPIF-- --FILE-- $value) { $this->$key = $value; } $this->unserialized = true; } } class OurClass implements BSON\Persistable { function bsonSerialize() { // Not tested with this test, so return empty array return array(); } function bsonUnserialize(array $data) { foreach ($data as $key => $value) { $this->$key = $value; } $this->unserialized = true; } } class TheirClass extends OurClass { } // Create base64-encoded class names for __pclass field's binary data $bMyClass = base64_encode('MyClass'); $bYourClass = base64_encode('YourClass'); $bOurClass = base64_encode('OurClass'); $bTheirClass = base64_encode('TheirClass'); $bInterface = base64_encode(BSON_NAMESPACE . '\Unserializable'); $testGroups = array( array( 'name' => 'DEFAULT TYPEMAP', 'typemap' => array(), 'tests' => array( '{ "foo": "yes", "bar" : false }', '{ "foo": "no", "array" : [ 5, 6 ] }', '{ "foo": "no", "obj" : { "embedded" : 3.14 } }', '{ "foo": "yes", "__pclass": "MyClass" }', '{ "foo": "yes", "__pclass": { "$type" : "80", "$binary" : "' . $bMyClass . '" } }', '{ "foo": "yes", "__pclass": { "$type" : "80", "$binary" : "' . $bYourClass . '" } }', '{ "foo": "yes", "__pclass": { "$type" : "80", "$binary" : "' . $bOurClass . '" } }', '{ "foo": "yes", "__pclass": { "$type" : "44", "$binary" : "' . $bYourClass . '" } }', ), ), array( 'name' => 'NONEXISTING CLASS', 'typemap' => array('root' => 'MissingClass'), 'tests' => array( '{ "foo": "yes" }', ), ), array( 'name' => 'DOES NOT IMPLEMENT UNSERIALIZABLE', 'typemap' => array('root' => 'MyClass'), 'tests' => array( '{ "foo": "yes", "__pclass": { "$type": "80", "$binary": "' . $bMyClass . '" } }', ), ), array( 'name' => 'IS NOT A CONCRETE CLASS', 'typemap' => array('root' => 'MongoDB\BSON\Unserializable'), 'tests' => array( '{ "foo": "yes" }', ), ), array( 'name' => 'IS NOT A CONCRETE CLASS VIA PCLASS', 'typemap' => array('root' => 'YourClass'), 'tests' => array( '{ "foo": "yes", "__pclass" : { "$type": "80", "$binary": "' . $bInterface . '" } }', ), ), array( 'name' => 'PCLASS OVERRIDES TYPEMAP (1)', 'typemap' => array('root' => 'YourClass'), 'tests' => array( '{ "foo": "yes", "__pclass" : { "$type": "80", "$binary": "' . $bMyClass . '" } }', '{ "foo": "yes", "__pclass" : { "$type": "80", "$binary": "' . $bOurClass . '" } }', '{ "foo": "yes", "__pclass" : { "$type": "80", "$binary": "' . $bTheirClass . '" } }', '{ "foo": "yes", "__pclass" : { "$type": "80", "$binary": "' . $bYourClass . '" } }', ), ), array( 'name' => 'PCLASS OVERRIDES TYPEMAP (2)', 'typemap' => array('root' => 'OurClass'), 'tests' => array( '{ "foo": "yes", "__pclass" : { "$type": "80", "$binary": "' . $bTheirClass . '" } }', ), ), array( 'name' => 'OBJECTS AS ARRAY', 'typemap' => array('root' => 'array', 'document' => 'array'), 'tests' => array( '{ "foo": "yes", "bar" : false }', '{ "foo": "no", "array" : [ 5, 6 ] }', '{ "foo": "no", "obj" : { "embedded" : 3.14 } }', '{ "foo": "yes", "__pclass": "MyClass" }', '{ "foo": "yes", "__pclass" : { "$type": "80", "$binary": "' . $bMyClass . '" } }', '{ "foo": "yes", "__pclass" : { "$type": "80", "$binary": "' . $bOurClass . '" } }', ), ), array( 'name' => 'OBJECTS AS STDCLASS', 'typemap' => array('root' => 'object', 'document' => 'object'), 'tests' => array( '{ "foo": "yes", "__pclass" : { "$type": "80", "$binary": "' . $bMyClass . '" } }', '{ "foo": "yes", "__pclass" : { "$type": "80", "$binary": "' . $bOurClass . '" } }', ), ), ); foreach ($testGroups as $testGroup) { printf("=== %s ===\n\n", $testGroup['name']); foreach ($testGroup['tests'] as $test) { echo $test, "\n"; $bson = fromJSON($test); try { var_dump(toPHP($bson, $testGroup['typemap'])); } catch (MongoDB\Driver\Exception\Exception $e) { echo $e->getMessage(), "\n"; } echo "\n"; } echo "\n"; } ?> ===DONE=== --EXPECTF-- === DEFAULT TYPEMAP === { "foo": "yes", "bar" : false } object(stdClass)#%d (2) { ["foo"]=> string(3) "yes" ["bar"]=> bool(false) } { "foo": "no", "array" : [ 5, 6 ] } object(stdClass)#%d (2) { ["foo"]=> string(2) "no" ["array"]=> array(2) { [0]=> int(5) [1]=> int(6) } } { "foo": "no", "obj" : { "embedded" : 3.14 } } object(stdClass)#%d (2) { ["foo"]=> string(2) "no" ["obj"]=> object(stdClass)#%d (1) { ["embedded"]=> float(3.14) } } { "foo": "yes", "__pclass": "MyClass" } object(stdClass)#%d (2) { ["foo"]=> string(3) "yes" ["__pclass"]=> string(7) "MyClass" } { "foo": "yes", "__pclass": { "$type" : "80", "$binary" : "TXlDbGFzcw==" } } object(stdClass)#%d (2) { ["foo"]=> string(3) "yes" ["__pclass"]=> object(%SBSON\Binary)#%d (2) { ["data"]=> string(7) "MyClass" ["type"]=> int(128) } } { "foo": "yes", "__pclass": { "$type" : "80", "$binary" : "WW91ckNsYXNz" } } object(stdClass)#%d (2) { ["foo"]=> string(3) "yes" ["__pclass"]=> object(MongoDB\BSON\Binary)#%d (2) { ["data"]=> string(9) "YourClass" ["type"]=> int(128) } } { "foo": "yes", "__pclass": { "$type" : "80", "$binary" : "T3VyQ2xhc3M=" } } object(OurClass)#%d (3) { ["foo"]=> string(3) "yes" ["__pclass"]=> object(MongoDB\BSON\Binary)#%d (2) { ["data"]=> string(8) "OurClass" ["type"]=> int(128) } ["unserialized"]=> bool(true) } { "foo": "yes", "__pclass": { "$type" : "44", "$binary" : "WW91ckNsYXNz" } } object(stdClass)#%d (2) { ["foo"]=> string(3) "yes" ["__pclass"]=> object(MongoDB\BSON\Binary)#%d (2) { ["data"]=> string(9) "YourClass" ["type"]=> int(68) } } === NONEXISTING CLASS === { "foo": "yes" } Class MissingClass does not exist === DOES NOT IMPLEMENT UNSERIALIZABLE === { "foo": "yes", "__pclass": { "$type": "80", "$binary": "TXlDbGFzcw==" } } Class MyClass does not implement MongoDB\BSON\Unserializable === IS NOT A CONCRETE CLASS === { "foo": "yes" } Class %SBSON\Unserializable is not instantiatable === IS NOT A CONCRETE CLASS VIA PCLASS === { "foo": "yes", "__pclass" : { "$type": "80", "$binary": "TW9uZ29EQlxCU09OXFVuc2VyaWFsaXphYmxl" } } object(YourClass)#%d (3) { ["foo"]=> string(3) "yes" ["__pclass"]=> object(%SBSON\Binary)#%d (2) { ["data"]=> string(27) "%SBSON\Unserializable" ["type"]=> int(128) } ["unserialized"]=> bool(true) } === PCLASS OVERRIDES TYPEMAP (1) === { "foo": "yes", "__pclass" : { "$type": "80", "$binary": "TXlDbGFzcw==" } } object(YourClass)#%d (3) { ["foo"]=> string(3) "yes" ["__pclass"]=> object(%SBSON\Binary)#%d (2) { ["data"]=> string(7) "MyClass" ["type"]=> int(128) } ["unserialized"]=> bool(true) } { "foo": "yes", "__pclass" : { "$type": "80", "$binary": "T3VyQ2xhc3M=" } } object(OurClass)#%d (3) { ["foo"]=> string(3) "yes" ["__pclass"]=> object(%SBSON\Binary)#%d (2) { ["data"]=> string(8) "OurClass" ["type"]=> int(128) } ["unserialized"]=> bool(true) } { "foo": "yes", "__pclass" : { "$type": "80", "$binary": "VGhlaXJDbGFzcw==" } } object(TheirClass)#%d (3) { ["foo"]=> string(3) "yes" ["__pclass"]=> object(%SBSON\Binary)#%d (2) { ["data"]=> string(10) "TheirClass" ["type"]=> int(128) } ["unserialized"]=> bool(true) } { "foo": "yes", "__pclass" : { "$type": "80", "$binary": "WW91ckNsYXNz" } } object(YourClass)#%d (3) { ["foo"]=> string(3) "yes" ["__pclass"]=> object(MongoDB\BSON\Binary)#%d (2) { ["data"]=> string(9) "YourClass" ["type"]=> int(128) } ["unserialized"]=> bool(true) } === PCLASS OVERRIDES TYPEMAP (2) === { "foo": "yes", "__pclass" : { "$type": "80", "$binary": "VGhlaXJDbGFzcw==" } } object(TheirClass)#%d (3) { ["foo"]=> string(3) "yes" ["__pclass"]=> object(%SBSON\Binary)#%d (2) { ["data"]=> string(10) "TheirClass" ["type"]=> int(128) } ["unserialized"]=> bool(true) } === OBJECTS AS ARRAY === { "foo": "yes", "bar" : false } array(2) { ["foo"]=> string(3) "yes" ["bar"]=> bool(false) } { "foo": "no", "array" : [ 5, 6 ] } array(2) { ["foo"]=> string(2) "no" ["array"]=> array(2) { [0]=> int(5) [1]=> int(6) } } { "foo": "no", "obj" : { "embedded" : 3.14 } } array(2) { ["foo"]=> string(2) "no" ["obj"]=> array(1) { ["embedded"]=> float(3.14) } } { "foo": "yes", "__pclass": "MyClass" } array(2) { ["foo"]=> string(3) "yes" ["__pclass"]=> string(7) "MyClass" } { "foo": "yes", "__pclass" : { "$type": "80", "$binary": "TXlDbGFzcw==" } } array(2) { ["foo"]=> string(3) "yes" ["__pclass"]=> object(%SBSON\Binary)#%d (2) { ["data"]=> string(7) "MyClass" ["type"]=> int(128) } } { "foo": "yes", "__pclass" : { "$type": "80", "$binary": "T3VyQ2xhc3M=" } } array(2) { ["foo"]=> string(3) "yes" ["__pclass"]=> object(%SBSON\Binary)#%d (2) { ["data"]=> string(8) "OurClass" ["type"]=> int(128) } } === OBJECTS AS STDCLASS === { "foo": "yes", "__pclass" : { "$type": "80", "$binary": "TXlDbGFzcw==" } } object(stdClass)#%d (2) { ["foo"]=> string(3) "yes" ["__pclass"]=> object(%SBSON\Binary)#%d (2) { ["data"]=> string(7) "MyClass" ["type"]=> int(128) } } { "foo": "yes", "__pclass" : { "$type": "80", "$binary": "T3VyQ2xhc3M=" } } object(stdClass)#%d (2) { ["foo"]=> string(3) "yes" ["__pclass"]=> object(%SBSON\Binary)#%d (2) { ["data"]=> string(8) "OurClass" ["type"]=> int(128) } } ===DONE=== mongodb-1.1.5/tests/bson/bson-toPHP_error-001.phpt0000664000175000017500000000414512673034026021452 0ustar jmikolajmikola--TEST-- BSON\toPHP(): Type map class must be both instantiatable and Unserializable --SKIPIF-- --FILE-- $className))); } catch (MongoDB\Driver\Exception\InvalidArgumentException $e) { echo $e->getMessage(), "\n"; } echo "\n"; } } ?> ===DONE=== --EXPECTF-- Test typeMap: { "array" : "MissingClass" } Class MissingClass does not exist Test typeMap: { "array" : "MyAbstractDocument" } Class MyAbstractDocument is not instantiatable Test typeMap: { "array" : "MyDocument" } Class MyDocument does not implement %SBSON\Unserializable Test typeMap: { "array" : "%SBSON\Unserializable" } Class %SBSON\Unserializable is not instantiatable Test typeMap: { "document" : "MissingClass" } Class MissingClass does not exist Test typeMap: { "document" : "MyAbstractDocument" } Class MyAbstractDocument is not instantiatable Test typeMap: { "document" : "MyDocument" } Class MyDocument does not implement %SBSON\Unserializable Test typeMap: { "document" : "%SBSON\Unserializable" } Class %SBSON\Unserializable is not instantiatable Test typeMap: { "root" : "MissingClass" } Class MissingClass does not exist Test typeMap: { "root" : "MyAbstractDocument" } Class MyAbstractDocument is not instantiatable Test typeMap: { "root" : "MyDocument" } Class MyDocument does not implement %SBSON\Unserializable Test typeMap: { "root" : "%SBSON\Unserializable" } Class %SBSON\Unserializable is not instantiatable ===DONE=== mongodb-1.1.5/tests/bson/bson-toPHP_error-002.phpt0000664000175000017500000000132412673034026021447 0ustar jmikolajmikola--TEST-- BSON\toPHP(): BSON decoding exceptions --SKIPIF-- --FILE-- getMessage(), "\n"; } } ?> ===DONE=== --EXPECTF-- Could not read document from BSON reader Reading document did not exhaust input buffer ===DONE=== mongodb-1.1.5/tests/bson/bson-toPHP_error-003.phpt0000664000175000017500000000140412673034026021447 0ustar jmikolajmikola--TEST-- BSON\toPHP(): BSON decoding exceptions for malformed documents --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException Could not read document from BSON reader OK: Got MongoDB\Driver\Exception\UnexpectedValueException Could not read document from BSON reader ===DONE=== mongodb-1.1.5/tests/bson/bson-toPHP_error-004.phpt0000664000175000017500000000377712673034026021467 0ustar jmikolajmikola--TEST-- BSON\toPHP(): BSON decoding exceptions for bson_iter_visit_all() failure --SKIPIF-- --FILE-- 'bar'])), // Invalid UTF-8 character in embedded document's field name str_replace('INVALID!', "INVALID\xFE", fromPHP(['foo' => ['INVALID!' => 'bar']])), // Invalid UTF-8 character in string within array field str_replace('INVALID!', "INVALID\xFE", fromPHP(['foo' => ['INVALID!']])), /* Note: we don't use a three-character string in the underflow case, as * the 4-byte string length and payload (i.e. three characters + null byte) * coincidentally satisfy the expected size for an 8-byte double. We also * don't use a four-character string, since its null byte would be * interpreted as the document terminator. The actual document terminator * would then remain in the buffer and trigger a "did not exhaust" error. */ pack('VCa*xVa*xx', 17, 1, 'foo', 3, 'ab'), // Invalid field type (underflow) pack('VCa*xVa*xx', 20, 1, 'foo', 6, 'abcde'), // Invalid field type (overflow) ); foreach ($tests as $bson) { echo throws(function() use ($bson) { toPHP($bson); }, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n"; } ?> ===DONE=== --EXPECTF-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException Could not convert BSON document to a PHP variable OK: Got MongoDB\Driver\Exception\UnexpectedValueException Could not convert BSON document to a PHP variable OK: Got MongoDB\Driver\Exception\UnexpectedValueException Could not convert BSON document to a PHP variable OK: Got MongoDB\Driver\Exception\UnexpectedValueException Could not convert BSON document to a PHP variable OK: Got MongoDB\Driver\Exception\UnexpectedValueException Could not convert BSON document to a PHP variable ===DONE=== mongodb-1.1.5/tests/bson/bson-unknown-001.phpt0000664000175000017500000000125512673034026020745 0ustar jmikolajmikola--TEST-- BSON Serializing a PHP resource should throw exception --SKIPIF-- --FILE-- STDERR); $b = fromPHP($a); }, "MongoDB\Driver\Exception\UnexpectedValueException"); throws(function() { $a = array("stderr" => STDERR, "stdout" => STDOUT); $b = fromPHP($a); }, "MongoDB\Driver\Exception\UnexpectedValueException"); ?> ===DONE=== --EXPECTF-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException OK: Got MongoDB\Driver\Exception\UnexpectedValueException ===DONE=== mongodb-1.1.5/tests/bson/bson-utcdatetime-001.phpt0000664000175000017500000000254412673034026021560 0ustar jmikolajmikola--TEST-- BSON BSON\UTCDateTime #001 --INI-- date.timezone=America/Los_Angeles --SKIPIF-- --FILE-- insert(array('_id' => 1, 'x' => $utcdatetime)); $manager->executeBulkWrite(NS, $bulk); $query = new MongoDB\Driver\Query(array('_id' => 1)); $cursor = $manager->executeQuery(NS, $query); $results = iterator_to_array($cursor); $tests = array( array($utcdatetime), array($results[0]->x), ); foreach($tests as $n => $test) { $s = fromPHP($test); echo "Test#{$n} ", $json = toJSON($s), "\n"; $bson = fromJSON($json); $testagain = toPHP($bson); var_dump(toJSON(fromPHP($test)), toJSON(fromPHP($testagain))); var_dump((object)$test == (object)$testagain); } ?> ===DONE=== --EXPECT-- Test#0 { "0" : { "$date" : 1416445411987 } } string(37) "{ "0" : { "$date" : 1416445411987 } }" string(37) "{ "0" : { "$date" : 1416445411987 } }" bool(true) Test#1 { "0" : { "$date" : 1416445411987 } } string(37) "{ "0" : { "$date" : 1416445411987 } }" string(37) "{ "0" : { "$date" : 1416445411987 } }" bool(true) ===DONE=== mongodb-1.1.5/tests/bson/bson-utcdatetime-002.phpt0000664000175000017500000000071112673034026021553 0ustar jmikolajmikola--TEST-- BSON BSON\UTCDateTime debug handler --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- object(%SBSON\UTCDateTime)#%d (%d) { ["milliseconds"]=> %rint\(|string\(13\) "|%r1416445411987%r"|\)%r } ===DONE=== mongodb-1.1.5/tests/bson/bson-utcdatetime-003.phpt0000664000175000017500000000101112673034026021546 0ustar jmikolajmikola--TEST-- BSON BSON\UTCDateTime construction from 64-bit integer --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- object(%SBSON\UTCDateTime)#%d (%d) { ["milliseconds"]=> int(1416445411987) } ===DONE=== mongodb-1.1.5/tests/bson/bson-utcdatetime-int-size.phpt0000664000175000017500000000213012673034026023011 0ustar jmikolajmikola--TEST-- Test for UTCDateTime and integer parsing --SKIPIF-- --INI-- date.timezone=UTC error_reporting=-1 dislay_errors=1 --FILE-- toDateTime()); echo "As string:\n"; $utcdatetime = new MongoDB\BSON\UTCDateTime('1416445411987'); var_dump($utcdatetime); var_dump($utcdatetime->toDateTime()); ?> --EXPECTF-- As number: object(MongoDB\BSON\UTCDateTime)#%d (1) { ["milliseconds"]=> %r(string\(13\) "|int\()%r1416445411987%r("|\))%r } object(DateTime)#%d (3) { ["date"]=> string(29) "2014-11-20 01:03:31.987000000" ["timezone_type"]=> int(1) ["timezone"]=> string(6) "+00:00" } As string: object(MongoDB\BSON\UTCDateTime)#%d (1) { ["milliseconds"]=> %r(string\(13\) "|int\()%r1416445411987%r("|\))%r } object(DateTime)#%d (3) { ["date"]=> string(29) "2014-11-20 01:03:31.987000000" ["timezone_type"]=> int(1) ["timezone"]=> string(6) "+00:00" } mongodb-1.1.5/tests/bson/bson-utcdatetime-todatetime-001.phpt0000664000175000017500000000073612673034026023716 0ustar jmikolajmikola--TEST-- BSON BSON\UTCDateTime::toDateTime() --INI-- date.timezone=America/Los_Angeles --SKIPIF-- --FILE-- toDateTime(); var_dump($datetime->format(DATE_RSS)); ?> ===DONE=== --EXPECTF-- string(31) "Thu, 20 Nov 2014 01:03:31 +0000" ===DONE=== mongodb-1.1.5/tests/bson/bson-utcdatetime-tostring-001.phpt0000664000175000017500000000063612673034026023427 0ustar jmikolajmikola--TEST-- BSON BSON\UTCDateTime::__toString() --INI-- date.timezone=America/Los_Angeles --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- string(13) "1416445411987" ===DONE=== mongodb-1.1.5/tests/bson/bson-utcdatetime_error-001.phpt0000664000175000017500000000107712673034026022771 0ustar jmikolajmikola--TEST-- BSON BSON\UTCDateTime #001 error --INI-- date.timezone=America/Los_Angeles --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE=== mongodb-1.1.5/tests/bson/bson-utcdatetime_error-002.phpt0000664000175000017500000000062212673034026022765 0ustar jmikolajmikola--TEST-- BSON BSON\UTCDateTime cannot be extended --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- Fatal error: Class MyUTCDateTime may not inherit from final class (%SBSON\UTCDateTime) in %s on line %d mongodb-1.1.5/tests/bson/bson-utcdatetime_error-003.phpt0000664000175000017500000000125412673034026022770 0ustar jmikolajmikola--TEST-- BSON BSON\UTCDateTime cannot be serialized --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- OK: Got Exception Serialization of '%SBSON\UTCDateTime' is not allowed OK: Got Exception Unserialization of '%SBSON\UTCDateTime' is not allowed ===DONE=== mongodb-1.1.5/tests/bson/bug0274.phpt0000664000175000017500000000260512673034026017103 0ustar jmikolajmikola--TEST-- Test for PHPC-274: zval_to_bson() should process BSON\Serializable instances --SKIPIF-- --FILE-- "class", "data"); } } class NumericArray implements BSON\Serializable { public function bsonSerialize() { return array(1, 2, 3); } } echo "Testing top-level AssociativeArray:\n"; $bson = fromPHP(new AssociativeArray); echo toJSON($bson), "\n"; echo "Encoded BSON:\n"; hex_dump($bson); echo "\nTesting top-level NumericArray:\n"; $bson = fromPHP(new NumericArray); echo toJSON($bson), "\n"; echo "Encoded BSON:\n"; hex_dump($bson); ?> ===DONE=== --EXPECT-- Testing top-level AssociativeArray: { "random" : "class", "0" : "data" } Encoded BSON: 0 : 23 00 00 00 02 72 61 6e 64 6f 6d 00 06 00 00 00 [#....random.....] 10 : 63 6c 61 73 73 00 02 30 00 05 00 00 00 64 61 74 [class..0.....dat] 20 : 61 00 00 [a..] Testing top-level NumericArray: { "0" : 1, "1" : 2, "2" : 3 } Encoded BSON: 0 : 1a 00 00 00 10 30 00 01 00 00 00 10 31 00 02 00 [.....0......1...] 10 : 00 00 10 32 00 03 00 00 00 00 [...2......] ===DONE=== mongodb-1.1.5/tests/bson/bug0325.phpt0000664000175000017500000000101112673034026017066 0ustar jmikolajmikola--TEST-- Test for PHPC-325: Memory leak decoding buffers with multiple documents --SKIPIF-- --FILE-- getMessage(), "\n"; } ?> ===DONE=== --EXPECTF-- Reading document did not exhaust input buffer ===DONE=== mongodb-1.1.5/tests/bson/bug0334-001.phpt0000664000175000017500000000124312673034026017373 0ustar jmikolajmikola--TEST-- PHPC-334: Injected __pclass should override a __pclass key in bsonSerialize() return value --SKIPIF-- --FILE-- "baz", "foo" => "bar", ); } function bsonUnserialize(array $data) { } } $bson = fromPHP(new MyClass); $php = toPHP($bson, array('root' => 'array')); var_dump($php['__pclass']->getData()); ?> ===DONE=== --EXPECT-- string(7) "MyClass" ===DONE=== mongodb-1.1.5/tests/bson/bug0334-002.phpt0000664000175000017500000000137512673034026017402 0ustar jmikolajmikola--TEST-- PHPC-334: Encoded BSON should never have multiple __pclass keys --SKIPIF-- --FILE-- "baz", "foo" => "bar", ); } function bsonUnserialize(array $data) { } } hex_dump(fromPHP(new MyClass)) ?> ===DONE=== --EXPECT-- 0 : 28 00 00 00 05 5f 5f 70 63 6c 61 73 73 00 07 00 [(....__pclass...] 10 : 00 00 80 4d 79 43 6c 61 73 73 02 66 6f 6f 00 04 [...MyClass.foo..] 20 : 00 00 00 62 61 72 00 00 [...bar..] ===DONE=== mongodb-1.1.5/tests/bson/bug0341.phpt0000664000175000017500000000152712673034026017100 0ustar jmikolajmikola--TEST-- PHPC-341: fromJSON() leaks when JSON contains array or object fields --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- object(stdClass)#%d (2) { ["foo"]=> string(3) "yes" ["bar"]=> bool(false) } object(stdClass)#%d (2) { ["foo"]=> string(2) "no" ["array"]=> array(2) { [0]=> int(5) [1]=> int(6) } } object(stdClass)#%d (2) { ["foo"]=> string(2) "no" ["obj"]=> object(stdClass)#%d (1) { ["embedded"]=> float(3.14) } } ===DONE=== mongodb-1.1.5/tests/bson/bug0347.phpt0000664000175000017500000000064212673034026017103 0ustar jmikolajmikola--TEST-- Test for PHPC-347: Memory leak decoding empty buffer --SKIPIF-- --FILE-- getMessage(), "\n"; } ?> ===DONE=== --EXPECTF-- Could not read document from BSON reader ===DONE=== mongodb-1.1.5/tests/bson/bug0528.phpt0000664000175000017500000000057212673034026017106 0ustar jmikolajmikola--TEST-- PHPC-528: Cannot append reference to BSON --SKIPIF-- --FILE-- &$embedded]; $bson = fromPHP($data); echo toJson(fromPHP($data)), "\n"; ?> ===DONE=== --EXPECT-- { "embedded" : [ "foo" ] } ===DONE=== mongodb-1.1.5/tests/bson/bug0531.phpt0000664000175000017500000000103012673034026017066 0ustar jmikolajmikola--TEST-- PHPC-531: Segfault due to double free by corrupt BSON visitor --SKIPIF-- --FILE-- "world"]); $bson[4] = 1; echo throws(function() use ($bson) { toPHP($bson); }, 'MongoDB\Driver\Exception\UnexpectedValueException'), "\n"; ?> ===DONE=== --EXPECTF-- OK: Got MongoDB\Driver\Exception\UnexpectedValueException Could not convert BSON document to a PHP variable ===DONE=== mongodb-1.1.5/tests/bson/bug0544.phpt0000664000175000017500000000437712673034026017113 0ustar jmikolajmikola--TEST-- PHPC-544: Consult SIZEOF_ZEND_LONG for 64-bit integer support --SKIPIF-- --INI-- mongodb.debug=stderr --FILE-- -2147483648], ['x' => 2147483647], ['x' => -4294967294], ['x' => 4294967294], ['x' => -4294967295], ['x' => 4294967295], ['x' => -9223372036854775807], ['x' => 9223372036854775807], ]; foreach ($tests as $test) { $bson = fromPHP($test); /* Note: Although libbson can parse the extended JSON representation for * 64-bit integers (i.e. "$numberLong"), it currently prints them as * doubles (see: https://jira.mongodb.org/browse/CDRIVER-375). */ printf("Test %s\n", toJSON($bson)); hex_dump($bson); var_dump(toPHP($bson)); echo "\n"; } ?> ===DONE=== --EXPECTF-- Test { "x" : -2147483648 } 0 : 0c 00 00 00 10 78 00 00 00 00 80 00 [.....x......] object(stdClass)#%d (%d) { ["x"]=> int(-2147483648) } Test { "x" : 2147483647 } 0 : 0c 00 00 00 10 78 00 ff ff ff 7f 00 [.....x......] object(stdClass)#%d (%d) { ["x"]=> int(2147483647) } Test { "x" : -4294967294 } 0 : 10 00 00 00 12 78 00 02 00 00 00 ff ff ff ff 00 [.....x..........] object(stdClass)#%d (%d) { ["x"]=> int(-4294967294) } Test { "x" : 4294967294 } 0 : 10 00 00 00 12 78 00 fe ff ff ff 00 00 00 00 00 [.....x..........] object(stdClass)#%d (%d) { ["x"]=> int(4294967294) } Test { "x" : -4294967295 } 0 : 10 00 00 00 12 78 00 01 00 00 00 ff ff ff ff 00 [.....x..........] object(stdClass)#%d (%d) { ["x"]=> int(-4294967295) } Test { "x" : 4294967295 } 0 : 10 00 00 00 12 78 00 ff ff ff ff 00 00 00 00 00 [.....x..........] object(stdClass)#%d (%d) { ["x"]=> int(4294967295) } Test { "x" : -9223372036854775807 } 0 : 10 00 00 00 12 78 00 01 00 00 00 00 00 00 80 00 [.....x..........] object(stdClass)#%d (%d) { ["x"]=> int(-9223372036854775807) } Test { "x" : 9223372036854775807 } 0 : 10 00 00 00 12 78 00 ff ff ff ff ff ff ff 7f 00 [.....x..........] object(stdClass)#%d (%d) { ["x"]=> int(9223372036854775807) } ===DONE=== mongodb-1.1.5/tests/bson/bug0592.phpt0000664000175000017500000000504212673034026017104 0ustar jmikolajmikola--TEST-- PHPC-592: Property name corrupted when unserializing 64-bit integer on 32-bit platform --SKIPIF-- --INI-- mongodb.debug=stderr --FILE-- ===DONE=== --EXPECTF-- Test { "x": { "$numberLong": "-2147483648" }} object(stdClass)#%d (%d) { ["x"]=> int(-2147483648) } Test { "x": { "$numberLong": "2147483647" }} object(stdClass)#%d (%d) { ["x"]=> int(2147483647) } Test { "x": { "$numberLong": "4294967295" }} [%s] PHONGO-BSON: WARNING > ENTRY: Integer overflow detected on your platform: 4294967295 object(stdClass)#%d (%d) { ["x"]=> string(10) "4294967295" } Test { "x": { "$numberLong": "9223372036854775807" }} [%s] PHONGO-BSON: WARNING > ENTRY: Integer overflow detected on your platform: 9223372036854775807 object(stdClass)#%d (%d) { ["x"]=> string(19) "9223372036854775807" } Test { "longFieldName": { "$numberLong": "-2147483648" }} object(stdClass)#%d (%d) { ["longFieldName"]=> int(-2147483648) } Test { "longFieldName": { "$numberLong": "2147483647" }} object(stdClass)#%d (%d) { ["longFieldName"]=> int(2147483647) } Test { "longFieldName": { "$numberLong": "4294967294" }} object(stdClass)#%d (%d) { ["longFieldName"]=> string(10) "4294967294" } Test { "longFieldName": { "$numberLong": "4294967295" }} [%s] PHONGO-BSON: WARNING > ENTRY: Integer overflow detected on your platform: 4294967295 object(stdClass)#%d (%d) { ["longFieldName"]=> string(10) "4294967295" } Test { "longFieldName": { "$numberLong": "9223372036854775807" }} [%s] PHONGO-BSON: WARNING > ENTRY: Integer overflow detected on your platform: 9223372036854775807 object(stdClass)#%d (%d) { ["longFieldName"]=> string(19) "9223372036854775807" } ===DONE=== mongodb-1.1.5/tests/bson/bug0623.phpt0000664000175000017500000000321312673034026017075 0ustar jmikolajmikola--TEST-- PHPC-623: Numeric keys limited to unsigned 32-bit integer --SKIPIF-- --INI-- mongodb.debug=stderr --FILE-- 'a', 'X9781449410247' => 'b', 9781449410248 => 'c', ], [ '4294967295' => 'a', '4294967296' => 'b', '4294967297' => 'c', ] ]; foreach ($tests as $test) { printf("Test %s\n", json_encode($test)); $bson = fromPHP($test); hex_dump($bson); echo toJSON($bson), "\n\n"; } ?> ===DONE=== --EXPECTF-- Test {"9781449410247":"a","X9781449410247":"b","9781449410248":"c"} 0 : 45 00 00 00 02 39 37 38 31 34 34 39 34 31 30 32 [E....97814494102] 10 : 34 37 00 02 00 00 00 61 00 02 58 39 37 38 31 34 [47.....a..X97814] 20 : 34 39 34 31 30 32 34 37 00 02 00 00 00 62 00 02 [49410247.....b..] 30 : 39 37 38 31 34 34 39 34 31 30 32 34 38 00 02 00 [9781449410248...] 40 : 00 00 63 00 00 [..c..] { "9781449410247" : "a", "X9781449410247" : "b", "9781449410248" : "c" } Test {"4294967295":"a","4294967296":"b","4294967297":"c"} 0 : 3b 00 00 00 02 34 32 39 34 39 36 37 32 39 35 00 [;....4294967295.] 10 : 02 00 00 00 61 00 02 34 32 39 34 39 36 37 32 39 [....a..429496729] 20 : 36 00 02 00 00 00 62 00 02 34 32 39 34 39 36 37 [6.....b..4294967] 30 : 32 39 37 00 02 00 00 00 63 00 00 [297.....c..] { "4294967295" : "a", "4294967296" : "b", "4294967297" : "c" } ===DONE=== mongodb-1.1.5/tests/bson/typemap-001.phpt0000664000175000017500000000755412673034026017776 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Cursor::setTypeMap(): Setting typemaps --SKIPIF-- --FILE-- insert(array('_id' => 1, 'bson_array' => array(1, 2, 3), 'bson_object' => array("string" => "keys", "for" => "ever"))); $bulk->insert(array('_id' => 2, 'bson_array' => array(4, 5, 6))); $manager->executeBulkWrite(NS, $bulk); function fetch($manager, $typemap = array()) { $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query(array('bson_array' => 1))); if ($typemap) { $cursor->setTypeMap($typemap); } $documents = $cursor->toArray(); return $documents; } echo "Default\n"; $documents = fetch($manager); var_dump($documents[0] instanceof stdClass); var_dump(is_array($documents[0]->bson_array)); var_dump($documents[0]->bson_object instanceof stdClass); echo "\nSetting to 'MyArrayObject' for arrays\n"; $documents = fetch($manager, array("array" => "MyArrayObject")); var_dump($documents[0] instanceof stdClass); var_dump($documents[0]->bson_array instanceof MyArrayObject); var_dump($documents[0]->bson_object instanceof stdClass); echo "\nSetting to 'MyArrayObject' for arrays, embedded, and root documents\n"; $documents = fetch($manager, array("array" => "MyArrayObject", "document" => "MyArrayObject", "root" => "MyArrayObject")); var_dump($documents[0] instanceof MyArrayObject); var_dump($documents[0]['bson_array'] instanceof MyArrayObject); var_dump($documents[0]['bson_object'] instanceof MyArrayObject); echo "\nSetting to 'array' for arrays, embedded, and root documents\n"; $documents = fetch($manager, array("array" => "array", "document" => "array", "root" => "array")); var_dump(is_array($documents[0])); var_dump(is_array($documents[0]['bson_array'])); var_dump(is_array($documents[0]['bson_object'])); echo "\nSetting to 'stdclass' for arrays and 'array' for embedded and root documents\n"; $documents = fetch($manager, array("array" => "stdclass", "document" => "array", "root" => "array")); var_dump(is_array($documents[0])); var_dump($documents[0]['bson_array'] instanceof stdClass); var_dump(is_array($documents[0]['bson_object'])); echo "\nSetting to 'array' for arrays, 'stdclass' for embedded document, and 'MyArrayObject' for root document\n"; $documents = fetch($manager, array("array" => "array", "document" => "stdclass", "root" => "MyArrayObject")); var_dump($documents[0] instanceof MyArrayObject); var_dump(is_array($documents[0]['bson_array'])); var_dump($documents[0]['bson_object'] instanceof stdClass); echo "\nSetting to 'stdclass' for arrays, embedded, and root documents\n"; $documents = fetch($manager, array("array" => "stdclass", "document" => "stdclass", "root" => "stdclass")); var_dump($documents[0] instanceof stdClass); var_dump($documents[0]->bson_array instanceof stdClass); var_dump($documents[0]->bson_object instanceof stdClass); ?> ===DONE=== --EXPECT-- Default bool(true) bool(true) bool(true) Setting to 'MyArrayObject' for arrays bool(true) bool(true) bool(true) Setting to 'MyArrayObject' for arrays, embedded, and root documents bool(true) bool(true) bool(true) Setting to 'array' for arrays, embedded, and root documents bool(true) bool(true) bool(true) Setting to 'stdclass' for arrays and 'array' for embedded and root documents bool(true) bool(true) bool(true) Setting to 'array' for arrays, 'stdclass' for embedded document, and 'MyArrayObject' for root document bool(true) bool(true) bool(true) Setting to 'stdclass' for arrays, embedded, and root documents bool(true) bool(true) bool(true) ===DONE=== mongodb-1.1.5/tests/bson/typemap-002.phpt0000664000175000017500000000452112673034026017766 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Cursor::setTypeMap(): Setting using type "object" --SKIPIF-- --FILE-- insert(array('_id' => 1, 'bson_array' => array(1, 2, 3), 'bson_object' => array("string" => "keys", "for" => "ever"))); $bulk->insert(array('_id' => 2, 'bson_array' => array(4, 5, 6))); $manager->executeBulkWrite(NS, $bulk); function fetch($manager, $typemap = array()) { $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query(array('bson_array' => 1))); if ($typemap) { $cursor->setTypeMap($typemap); } $documents = $cursor->toArray(); return $documents; } echo "Setting to 'object' for arrays and 'array' for embedded and root documents\n"; $documents = fetch($manager, array("array" => "object", "document" => "array", "root" => "array")); var_dump(is_array($documents[0])); var_dump($documents[0]['bson_array'] instanceof stdClass); var_dump(is_array($documents[0]['bson_object'])); echo "\nSetting to 'array' for arrays and 'object' for embedded and root documents\n"; $documents = fetch($manager, array("array" => "array", "document" => "object", "root" => "object")); var_dump($documents[0] instanceof stdClass); var_dump(is_array($documents[0]->bson_array)); var_dump($documents[0]->bson_object instanceof stdClass); echo "\nSetting to 'object' for arrays, embedded, and root documents\n"; $documents = fetch($manager, array("array" => "object", "document" => "object", "root" => "object")); var_dump($documents[0] instanceof stdClass); var_dump($documents[0]->bson_array instanceof stdClass); var_dump($documents[0]->bson_object instanceof stdClass); ?> ===DONE=== --EXPECT-- Setting to 'object' for arrays and 'array' for embedded and root documents bool(true) bool(true) bool(true) Setting to 'array' for arrays and 'object' for embedded and root documents bool(true) bool(true) bool(true) Setting to 'object' for arrays, embedded, and root documents bool(true) bool(true) bool(true) ===DONE=== mongodb-1.1.5/tests/bulk/bulkwrite-delete-001.phpt0000664000175000017500000000367712673034026021565 0ustar jmikolajmikola--TEST-- MongoDB\Driver\BulkWrite::delete() should always encode __pclass for Persistable objects --SKIPIF-- --FILE-- id = $id; $this->child = $child; } public function bsonSerialize() { return [ '_id' => $this->id, 'child' => $this->child, ]; } public function bsonUnserialize(array $data) { $this->id = $data['_id']; $this->child = $data['child']; } } $manager = new MongoDB\Driver\Manager(STANDALONE); $document = new MyClass('foo', new MyClass('bar', new MyClass('baz'))); $bulk = new MongoDB\Driver\BulkWrite(); $bulk->insert($document); $result = $manager->executeBulkWrite(NS, $bulk); printf("Inserted %d document(s)\n", $result->getInsertedCount()); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query([])); var_dump($cursor->toArray()); $bulk = new MongoDB\Driver\BulkWrite(); $bulk->delete($document); $result = $manager->executeBulkWrite(NS, $bulk); printf("Deleted %d document(s)\n", $result->getDeletedCount()); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query([])); var_dump($cursor->toArray()); ?> ===DONE=== --EXPECTF-- Inserted 1 document(s) array(1) { [0]=> object(MyClass)#%d (%d) { ["id":"MyClass":private]=> string(3) "foo" ["child":"MyClass":private]=> object(MyClass)#%d (%d) { ["id":"MyClass":private]=> string(3) "bar" ["child":"MyClass":private]=> object(MyClass)#%d (%d) { ["id":"MyClass":private]=> string(3) "baz" ["child":"MyClass":private]=> NULL } } } } Deleted 1 document(s) array(0) { } ===DONE=== mongodb-1.1.5/tests/bulk/bulkwrite-insert-001.phpt0000664000175000017500000000315512673034026021616 0ustar jmikolajmikola--TEST-- MongoDB\Driver\BulkWrite::insert() should always encode __pclass for Persistable objects --SKIPIF-- --FILE-- id = $id; $this->child = $child; } public function bsonSerialize() { return [ '_id' => $this->id, 'child' => $this->child, ]; } public function bsonUnserialize(array $data) { $this->id = $data['_id']; $this->child = $data['child']; } } $manager = new MongoDB\Driver\Manager(STANDALONE); $bulk = new MongoDB\Driver\BulkWrite(); $bulk->insert(new MyClass('foo', new MyClass('bar', new MyClass('baz')))); $result = $manager->executeBulkWrite(NS, $bulk); printf("Inserted %d document(s)\n", $result->getInsertedCount()); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query([])); var_dump($cursor->toArray()); ?> ===DONE=== --EXPECTF-- Inserted 1 document(s) array(1) { [0]=> object(MyClass)#%d (%d) { ["id":"MyClass":private]=> string(3) "foo" ["child":"MyClass":private]=> object(MyClass)#%d (%d) { ["id":"MyClass":private]=> string(3) "bar" ["child":"MyClass":private]=> object(MyClass)#%d (%d) { ["id":"MyClass":private]=> string(3) "baz" ["child":"MyClass":private]=> NULL } } } } ===DONE=== mongodb-1.1.5/tests/bulk/bulkwrite-update-001.phpt0000664000175000017500000000472312673034026021576 0ustar jmikolajmikola--TEST-- MongoDB\Driver\BulkWrite::update() should always encode __pclass for Persistable objects --SKIPIF-- --FILE-- id = $id; $this->child = $child; } public function bsonSerialize() { return [ '_id' => $this->id, 'child' => $this->child, ]; } public function bsonUnserialize(array $data) { $this->id = $data['_id']; $this->child = $data['child']; } } $manager = new MongoDB\Driver\Manager(STANDALONE); $document = new MyClass('foo', new MyClass('bar', new MyClass('baz'))); $bulk = new MongoDB\Driver\BulkWrite(); $bulk->update( ['_id' => 'foo'], $document, ['upsert' => true] ); $result = $manager->executeBulkWrite(NS, $bulk); printf("Upserted %d document(s)\n", $result->getUpsertedCount()); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query([])); var_dump($cursor->toArray()); $bulk = new MongoDB\Driver\BulkWrite(); $bulk->update( $document, ['$set' => ['child' => new MyClass('yip', new MyClass('yap'))]] ); $result = $manager->executeBulkWrite(NS, $bulk); printf("Modified %d document(s)\n", $result->getModifiedCount()); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query([])); var_dump($cursor->toArray()); ?> ===DONE=== --EXPECTF-- Upserted 1 document(s) array(1) { [0]=> object(MyClass)#%d (%d) { ["id":"MyClass":private]=> string(3) "foo" ["child":"MyClass":private]=> object(MyClass)#%d (%d) { ["id":"MyClass":private]=> string(3) "bar" ["child":"MyClass":private]=> object(MyClass)#%d (%d) { ["id":"MyClass":private]=> string(3) "baz" ["child":"MyClass":private]=> NULL } } } } Modified 1 document(s) array(1) { [0]=> object(MyClass)#%d (%d) { ["id":"MyClass":private]=> string(3) "foo" ["child":"MyClass":private]=> object(MyClass)#%d (%d) { ["id":"MyClass":private]=> string(3) "yip" ["child":"MyClass":private]=> object(MyClass)#%d (%d) { ["id":"MyClass":private]=> string(3) "yap" ["child":"MyClass":private]=> NULL } } } } ===DONE=== mongodb-1.1.5/tests/bulk/bulkwrite_error-001.phpt0000664000175000017500000000060412673034026021521 0ustar jmikolajmikola--TEST-- MongoDB\Driver\BulkWrite cannot be extended --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- Fatal error: Class MyBulkWrite may not inherit from final class (MongoDB\Driver\BulkWrite) in %s on line %d mongodb-1.1.5/tests/bulk/write-0001.phpt0000664000175000017500000000432312673034026017514 0ustar jmikolajmikola--TEST-- MongoDB\Driver\BulkWrite: #001 Variety Bulk --SKIPIF-- --FILE-- insert(array("my" => "value")); $bulk->insert(array("my" => "value", "foo" => "bar")); $bulk->insert(array("my" => "value", "foo" => "bar")); var_dump($bulk); $bulk->delete(array("my" => "value", "foo" => "bar"), array("limit" => 1)); var_dump($bulk); $bulk->update(array("foo" => "bar"), array('$set' => array("foo" => "baz")), array("limit" => 1, "upsert" => 0)); var_dump($bulk); $retval = $manager->executeBulkWrite(NS, $bulk); var_dump($bulk); printf("Inserted: %d\n", getInsertCount($retval)); printf("Deleted: %d\n", getDeletedCount($retval)); printf("Updated: %d\n", getModifiedCount($retval)); printf("Upserted: %d\n", getUpsertedCount($retval)); foreach(getWriteErrors($retval) as $error) { printf("WriteErrors: %", $error); } ?> ===DONE=== --EXPECTF-- object(MongoDB\Driver\BulkWrite)#%d (%d) { ["database"]=> NULL ["collection"]=> NULL ["ordered"]=> bool(true) ["executed"]=> bool(false) ["server_id"]=> int(0) ["write_concern"]=> NULL } object(MongoDB\Driver\BulkWrite)#%d (%d) { ["database"]=> NULL ["collection"]=> NULL ["ordered"]=> bool(true) ["executed"]=> bool(false) ["server_id"]=> int(0) ["write_concern"]=> NULL } object(MongoDB\Driver\BulkWrite)#%d (%d) { ["database"]=> NULL ["collection"]=> NULL ["ordered"]=> bool(true) ["executed"]=> bool(false) ["server_id"]=> int(0) ["write_concern"]=> NULL } object(MongoDB\Driver\BulkWrite)#%d (%d) { ["database"]=> NULL ["collection"]=> NULL ["ordered"]=> bool(true) ["executed"]=> bool(false) ["server_id"]=> int(0) ["write_concern"]=> NULL } object(MongoDB\Driver\BulkWrite)#%d (%d) { ["database"]=> string(6) "phongo" ["collection"]=> string(15) "bulk_write_0001" ["ordered"]=> bool(true) ["executed"]=> bool(true) ["server_id"]=> int(1) ["write_concern"]=> NULL } Inserted: 3 Deleted: 1 Updated: 1 Upserted: 0 ===DONE=== mongodb-1.1.5/tests/bulk/write-0002.phpt0000664000175000017500000000325512673034026017520 0ustar jmikolajmikola--TEST-- MongoDB\Driver\BulkWrite: #002 Get the generated ID --SKIPIF-- --FILE-- "Hannes", "country" => "USA", "gender" => "male"); $hayley = array("name" => "Bayley", "country" => "USA", "gender" => "female"); $insertBulk = new \MongoDB\Driver\BulkWrite(['ordered' => true]); $hannes_id = $insertBulk->insert($hannes); $hayley_id = $insertBulk->insert($hayley); $w = 1; $wtimeout = 1000; $writeConcern = new \MongoDB\Driver\WriteConcern($w, $wtimeout); var_dump($insertBulk); $result = $manager->executeBulkWrite(NS, $insertBulk, $writeConcern); var_dump($insertBulk); assert($result instanceof \MongoDB\Driver\WriteResult); printf( "Inserted %d documents to %s\n", $result->getInsertedCount(), $result->getServer()->getHost() ); printf("hannes: %s\nhayley: %s\n", $hannes_id, $hayley_id); ?> ===DONE=== --EXPECTF-- object(MongoDB\Driver\BulkWrite)#%d (%d) { ["database"]=> NULL ["collection"]=> NULL ["ordered"]=> bool(true) ["executed"]=> bool(false) ["server_id"]=> int(0) ["write_concern"]=> NULL } object(MongoDB\Driver\BulkWrite)#%d (%d) { ["database"]=> string(6) "phongo" ["collection"]=> string(15) "bulk_write_0002" ["ordered"]=> bool(true) ["executed"]=> bool(true) ["server_id"]=> int(1) ["write_concern"]=> array(%d) { ["w"]=> int(1) ["wmajority"]=> bool(false) ["wtimeout"]=> int(1000) ["journal"]=> NULL } } Inserted 2 documents to %s hannes: %s hayley: %s ===DONE=== mongodb-1.1.5/tests/bulk/write-0003.phpt0000664000175000017500000000453712673034026017525 0ustar jmikolajmikola--TEST-- MongoDB\Driver\BulkWrite: #003 executed multiple times --SKIPIF-- --FILE-- insert(['x' => 1]); $result = $manager->executeBulkWrite(NS, $insertBulk); printf("Inserted %d document(s)\n", $result->getInsertedCount()); $insertBulk = new MongoDB\Driver\BulkWrite; $insertBulk->insert(['x' => 1]); $result = $manager->executeBulkWrite(NS, $insertBulk); printf("Inserted %d document(s)\n", $result->getInsertedCount()); try { $result = $manager->executeBulkWrite(NS, $insertBulk); printf("Inserted %d document(s)\n", $result->getInsertedCount()); } catch (MongoDB\Driver\Exception\BulkWriteException $e) { printf("Write error: %s\n", $e->getWriteResult()->getWriteErrors()[0]->getMessage()); } $updateBulk = new MongoDB\Driver\BulkWrite; $updateBulk->update([], ['$inc' => ['x' => 1]]); $result = $manager->executeBulkWrite(NS, $updateBulk); printf("Updated %d document(s)\n", $result->getModifiedCount()); $result = $manager->executeBulkWrite(NS, $updateBulk); printf("Updated %d document(s)\n", $result->getModifiedCount()); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query([])); var_dump($cursor->toArray()); $deleteBulk = new MongoDB\Driver\BulkWrite; $deleteBulk->delete([], ['limit' => 1]); $result = $manager->executeBulkWrite(NS, $deleteBulk); printf("Deleted %d document(s)\n", $result->getDeletedCount()); $result = $manager->executeBulkWrite(NS, $deleteBulk); printf("Deleted %d document(s)\n", $result->getDeletedCount()); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query([])); var_dump($cursor->toArray()); ?> ===DONE=== --EXPECTF-- Inserted 1 document(s) Inserted 1 document(s) Write error: E11000 duplicate key error%s Updated 1 document(s) Updated 1 document(s) array(2) { [0]=> object(stdClass)#%d (%d) { ["_id"]=> object(MongoDB\BSON\ObjectID)#%d (%d) { ["oid"]=> string(24) "%x" } ["x"]=> int(3) } [1]=> object(stdClass)#%d (%d) { ["_id"]=> object(MongoDB\BSON\ObjectID)#%d (%d) { ["oid"]=> string(24) "%x" } ["x"]=> int(1) } } Deleted 1 document(s) Deleted 1 document(s) array(0) { } ===DONE=== mongodb-1.1.5/tests/connect/replicaset-seedlist-001.phpt0000664000175000017500000000131712673034026022743 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager: Connecting to Replica Set with only secondary in seedlist --SKIPIF-- --FILE-- insert(array("_id" => 1, "x" => 2, "y" => 3)); $bulk->insert(array("_id" => 2, "x" => 3, "y" => 4)); $bulk->insert(array("_id" => 3, "x" => 4, "y" => 5)); $manager->executeBulkWrite(NS, $bulk); ?> ===DONE=== --EXPECT-- ===DONE=== mongodb-1.1.5/tests/connect/replicaset-seedlist-002.phpt0000664000175000017500000000131512673034026022742 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager: Connecting to Replica Set with only arbiter in seedlist --SKIPIF-- --FILE-- insert(array("_id" => 1, "x" => 2, "y" => 3)); $bulk->insert(array("_id" => 2, "x" => 3, "y" => 4)); $bulk->insert(array("_id" => 3, "x" => 4, "y" => 5)); $manager->executeBulkWrite(NS, $bulk); ?> ===DONE=== --EXPECT-- ===DONE=== mongodb-1.1.5/tests/connect/standalone-auth-0001.phpt0000664000175000017500000000215412673034026022145 0ustar jmikolajmikola--TEST-- Connect to MongoDB with using default auth mechanism --SKIPIF-- --FILE-- insert(array("my" => "value")); $bulk->insert(array("my" => "value", "foo" => "bar")); $bulk->insert(array("my" => "value", "foo" => "bar")); $bulk->delete(array("my" => "value", "foo" => "bar"), array("limit" => 1)); $bulk->update(array("foo" => "bar"), array('$set' => array("foo" => "baz")), array("limit" => 1, "upsert" => 0)); $retval = $manager->executeBulkWrite(NS, $bulk); printf("Inserted: %d\n", getInsertCount($retval)); printf("Deleted: %d\n", getDeletedCount($retval)); printf("Updated: %d\n", getModifiedCount($retval)); printf("Upserted: %d\n", getUpsertedCount($retval)); foreach(getWriteErrors($retval) as $error) { printf("WriteErrors: %", $error); } ?> ===DONE=== --EXPECT-- Inserted: 3 Deleted: 1 Updated: 1 Upserted: 0 ===DONE=== mongodb-1.1.5/tests/connect/standalone-auth-0002.phpt0000664000175000017500000000153112673034026022144 0ustar jmikolajmikola--TEST-- Connect to MongoDB with using default auth mechanism #002 --SKIPIF-- --FILE-- insert(array("my" => "value")); throws(function() use($manager, $bulk) { $retval = $manager->executeBulkWrite(NS, $bulk); }, "MongoDB\Driver\Exception\AuthenticationException"); ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\AuthenticationException ===DONE=== mongodb-1.1.5/tests/connect/standalone-plain-0001.phpt0000664000175000017500000000371212673034026022310 0ustar jmikolajmikola--TEST-- Connect to MongoDB with using PLAIN auth mechanism --SKIPIF-- --FILE-- "bugs", "roles" => array(array("role" => "readWrite", "db" => DATABASE_NAME)), ); $command = new MongoDB\Driver\Command($cmd); try { $result = $adminmanager->executeCommand('$external', $command); echo "User Created\n"; } catch(Exception $e) { echo $e->getMessage(), "\n"; } $username = "bugs"; $password = "password"; $database = '$external'; $dsn = sprintf("mongodb://%s:%s@%s:%d/%s?authMechanism=PLAIN", $username, $password, $parsed["host"], $parsed["port"], $database); $manager = new MongoDB\Driver\Manager($dsn); $bulk = new MongoDB\Driver\BulkWrite(); $bulk->insert(array("very" => "important")); try { $manager->executeBulkWrite(NS, $bulk); $query = new MongoDB\Driver\Query(array("very" => "important")); $cursor = $manager->executeQuery(NS, $query); foreach($cursor as $document) { var_dump($document->very); } $cmd = new MongoDB\Driver\Command(array("drop" => COLLECTION_NAME)); $result = $manager->executeCommand(DATABASE_NAME, $cmd); } catch(Exception $e) { printf("Caught %s: %s\n", get_class($e), $e->getMessage()); } $cmd = array( "dropUser" => "bugs", ); $command = new MongoDB\Driver\Command($cmd); try { $result = $adminmanager->executeCommand('$external', $command); echo "User deleted\n"; } catch(Exception $e) { echo $e->getMessage(), "\n"; } ?> ===DONE=== --EXPECT-- User Created string(9) "important" User deleted ===DONE=== mongodb-1.1.5/tests/connect/standalone-plain-0002.phpt0000664000175000017500000000321512673034026022307 0ustar jmikolajmikola--TEST-- Connect to MongoDB with using PLAIN auth mechanism #002 --SKIPIF-- --FILE-- "bugs", "roles" => array(array("role" => "readWrite", "db" => DATABASE_NAME)), ); $command = new MongoDB\Driver\Command($cmd); try { $result = $adminmanager->executeCommand('$external', $command); echo "User Created\n"; } catch(Exception $e) { echo $e->getMessage(), "\n"; } $username = "bugs"; $password = "wrong-password"; $database = '$external'; $dsn = sprintf("mongodb://%s:%s@%s:%d/%s?authMechanism=PLAIN", $username, $password, $parsed["host"], $parsed["port"], $database); $manager = new MongoDB\Driver\Manager($dsn); $bulk = new MongoDB\Driver\BulkWrite(); $bulk->insert(array("very" => "important")); throws(function() use($manager, $bulk) { $manager->executeBulkWrite(NS, $bulk); }, "MongoDB\Driver\Exception\AuthenticationException"); $cmd = array( "dropUser" => "bugs", ); $command = new MongoDB\Driver\Command($cmd); try { $result = $adminmanager->executeCommand('$external', $command); echo "User deleted\n"; } catch(Exception $e) { echo $e->getMessage(), "\n"; } ?> ===DONE=== --EXPECT-- User Created OK: Got MongoDB\Driver\Exception\AuthenticationException User deleted ===DONE=== mongodb-1.1.5/tests/connect/standalone-ssl-0001.phpt0000664000175000017500000000264112673034026022006 0ustar jmikolajmikola--TEST-- Connect to MongoDB with using SSL without verifying anything --SKIPIF-- --FILE-- array( "verify_peer" => false, "verify_peer_name" => false, "allow_self_signed" => true, ), ); $context = stream_context_create($opts); $dsn = sprintf("%s/?ssl=true", STANDALONE_SSL); $manager = new MongoDB\Driver\Manager($dsn, array(), array("context" => $context)); $bulk = new MongoDB\Driver\BulkWrite; $bulk->insert(array("my" => "value")); $bulk->insert(array("my" => "value", "foo" => "bar")); $bulk->insert(array("my" => "value", "foo" => "bar")); $bulk->delete(array("my" => "value", "foo" => "bar"), array("limit" => 1)); $bulk->update(array("foo" => "bar"), array('$set' => array("foo" => "baz")), array("limit" => 1, "upsert" => 0)); $retval = $manager->executeBulkWrite(NS, $bulk); printf("Inserted: %d\n", getInsertCount($retval)); printf("Deleted: %d\n", getDeletedCount($retval)); printf("Updated: %d\n", getModifiedCount($retval)); printf("Upserted: %d\n", getUpsertedCount($retval)); foreach(getWriteErrors($retval) as $error) { printf("WriteErrors: %", $error); } ?> ===DONE=== --EXPECT-- Inserted: 3 Deleted: 1 Updated: 1 Upserted: 0 ===DONE=== mongodb-1.1.5/tests/connect/standalone-ssl-0002.phpt0000664000175000017500000000367612673034026022020 0ustar jmikolajmikola--TEST-- Connect to MongoDB with using SSL and verify the stream --SKIPIF-- --FILE-- $current && $current < $to) { return true; } return false; } $opts = array( "ssl" => array( "peer_name" => "WRONG PEER NAME", "verify_peer" => true, "verify_peer_name" => true, "allow_self_signed" => false, "cafile" => $SSL_DIR . "/ca.pem", /* Defaults to openssl.cafile */ "capath" => $SSL_DIR, /* Defaults to openssl.capath */ "local_cert" => $SSL_DIR . "/client.pem", "passphrase" => "Very secretive client.pem passphrase", "verify_depth" => 5, "ciphers" => "HIGH:!EXPORT:!aNULL@STRENGTH", "capture_peer_cert" => true, "capture_peer_cert_chain" => true, "SNI_enabled" => true, "disable_compression" => false, "peer_fingerprint" => strtolower("FC16D0861C31D29E90A8A5C832469AB10EE7F4DD"), ), ); $context = stream_context_create($opts); $manager = new MongoDB\Driver\Manager($dsn, array(), array("context" => $context)); echo throws(function() use($manager) { $bulk = new MongoDB\Driver\BulkWrite; $bulk->insert(array("my" => "value")); $retval = $manager->executeBulkWrite(NS, $bulk); }, "MongoDB\\Driver\\Exception\\SSLConnectionException", "executeBulkWrite"), "\n"; ?> ===DONE=== --EXPECTF-- OK: Got MongoDB\Driver\Exception\SSLConnectionException thrown from executeBulkWrite %s ===DONE=== mongodb-1.1.5/tests/connect/standalone-ssl-0003.phpt0000664000175000017500000000250112673034026022003 0ustar jmikolajmikola--TEST-- Connect to MongoDB with using SSL without verifying anything --SKIPIF-- --FILE-- false, "verify_peer_name" => false, "allow_self_signed" => true, ); $dsn = sprintf("%s/?ssl=true", STANDALONE_SSL); $manager = new MongoDB\Driver\Manager($dsn, array(), $opts); $bulk = new MongoDB\Driver\BulkWrite; $bulk->insert(array("my" => "value")); $bulk->insert(array("my" => "value", "foo" => "bar")); $bulk->insert(array("my" => "value", "foo" => "bar")); $bulk->delete(array("my" => "value", "foo" => "bar"), array("limit" => 1)); $bulk->update(array("foo" => "bar"), array('$set' => array("foo" => "baz")), array("limit" => 1, "upsert" => 0)); $retval = $manager->executeBulkWrite(NS, $bulk); printf("Inserted: %d\n", getInsertCount($retval)); printf("Deleted: %d\n", getDeletedCount($retval)); printf("Updated: %d\n", getModifiedCount($retval)); printf("Upserted: %d\n", getUpsertedCount($retval)); foreach(getWriteErrors($retval) as $error) { printf("WriteErrors: %", $error); } ?> ===DONE=== --EXPECT-- Inserted: 3 Deleted: 1 Updated: 1 Upserted: 0 ===DONE=== mongodb-1.1.5/tests/connect/standalone-ssl-0004.phpt0000664000175000017500000000302412673034026022005 0ustar jmikolajmikola--TEST-- Connect to MongoDB with using SSL and verify the stream --SKIPIF-- --FILE-- "WRONG PEER NAME", "verify_peer" => true, "verify_peer_name" => true, "allow_self_signed" => false, "cafile" => $SSL_DIR . "/ca.pem", /* Defaults to openssl.cafile */ "ciphers" => "HIGH:!EXPORT:!aNULL@STRENGTH", ); $manager = new MongoDB\Driver\Manager($dsn, array(), $opts); echo throws(function() use($manager) { $bulk = new MongoDB\Driver\BulkWrite; $bulk->insert(array("my" => "value")); $retval = $manager->executeBulkWrite(NS, $bulk); }, "MongoDB\\Driver\\Exception\\SSLConnectionException", "executeBulkWrite"), "\n"; echo "Changing to server\n"; $opts["peer_name"] = "server"; $manager = new MongoDB\Driver\Manager($dsn, array(), $opts); $bulk = new MongoDB\Driver\BulkWrite; $bulk->insert(array("my" => "value")); $retval = $manager->executeBulkWrite(NS, $bulk); printf("Inserted: %d\n", $retval->getInsertedCount()); ?> ===DONE=== --EXPECTF-- OK: Got MongoDB\Driver\Exception\SSLConnectionException thrown from executeBulkWrite %s Changing to server Inserted: 1 ===DONE=== mongodb-1.1.5/tests/connect/standalone-ssl-0005.phpt0000664000175000017500000000421012673034026022004 0ustar jmikolajmikola--TEST-- Connect to MongoDB with using SSL and verify the stream --SKIPIF-- --FILE-- $current && $current < $to) { return true; } return false; } $opts = array( "ssl" => array( "peer_name" => "server", "verify_peer" => true, "verify_peer_name" => true, "allow_self_signed" => false, "cafile" => $SSL_DIR . "/ca.pem", /* Defaults to openssl.cafile */ "capath" => $SSL_DIR, /* Defaults to openssl.capath */ "local_cert" => $SSL_DIR . "/client.pem", "passphrase" => "Very secretive client.pem passphrase", "verify_depth" => 5, "ciphers" => "HIGH:!EXPORT:!aNULL@STRENGTH", "capture_peer_cert" => true, "capture_peer_cert_chain" => true, "SNI_enabled" => true, "disable_compression" => false, "peer_fingerprint" => strtolower("FC16D0861C31D29E90A8A5C832469AB10EE7F4DD"), ), ); $context = stream_context_create($opts); $manager = new MongoDB\Driver\Manager($dsn, array(), array("context" => $context)); $bulk = new MongoDB\Driver\BulkWrite; $bulk->insert(array("my" => "value")); $retval = $manager->executeBulkWrite(NS, $bulk); printf("Inserted: %d\n", $retval->getInsertedCount()); $opts = stream_context_get_params($context); $cert = openssl_x509_parse($opts["options"]["ssl"]["peer_certificate"]); printf("Certificate name: %s\n", $cert["name"]); printf("Certificate valid (not expired): %s\n", isValid($cert) ? "OK" : "NO"); ?> ===DONE=== --EXPECTF-- Inserted: 1 Certificate name: /CN=server/OU=Kernel/O=MongoDB/L=New York City/ST=New York/C=US Certificate valid (not expired): NO ===DONE=== mongodb-1.1.5/tests/connect/standalone-ssl-0006.phpt0000664000175000017500000000262312673034026022013 0ustar jmikolajmikola--TEST-- Connect to MongoDB with using SSL and default options --SKIPIF-- --FILE-- true, "serverselectiontimeoutms" => 100)); $bulk = new MongoDB\Driver\BulkWrite; $bulk->insert(array("my" => "value")); throws(function() use ($manager, $bulk) { $retval = $manager->executeBulkWrite(NS, $bulk); }, "MongoDB\Driver\Exception\SSLConnectionException"); /* Disable all CA and hostname checks */ $opts = array( "ssl" => array( "verify_peer" => false, "verify_peer_name" => false, "allow_self_signed" => true, ), ); $context = stream_context_create($opts); $uriopts = array("ssl" => true, "serverselectiontimeoutms" => 100); $ctxopts = array("context" => $context); $manager = new MongoDB\Driver\Manager(STANDALONE_SSL, $uriopts, $ctxopts); $bulk = new MongoDB\Driver\BulkWrite; $bulk->insert(array("my" => "value")); $retval = $manager->executeBulkWrite(NS, $bulk); printf("Inserted %d documents\n", $retval->getInsertedCount()); ?> ===DONE=== --EXPECTF-- OK: Got MongoDB\Driver\Exception\SSLConnectionException Inserted 1 documents ===DONE=== mongodb-1.1.5/tests/connect/standalone-x509-0001.phpt0000664000175000017500000000346012673034026021712 0ustar jmikolajmikola--TEST-- Connect to MongoDB with using SSL and X.509 auth (stream context) --SKIPIF-- --FILE-- array( "peer_name" => "server", "verify_peer" => true, "verify_peer_name" => true, "allow_self_signed" => false, "cafile" => $SSL_DIR . "/ca.pem", /* Defaults to openssl.cafile */ "capath" => $SSL_DIR, /* Defaults to openssl.capath */ "local_cert" => $SSL_DIR . "/client.pem", "passphrase" => "qwerty", "verify_depth" => 5, "ciphers" => "HIGH:!EXPORT:!aNULL@STRENGTH", "capture_peer_cert" => true, "capture_peer_cert_chain" => true, "SNI_enabled" => true, "disable_compression" => false, "peer_fingerprint" => strtolower("FC16D0861C31D29E90A8A5C832469AB10EE7F4DD"), ), ); $context = stream_context_create($opts); try { $dsn = sprintf("%s&ssl=true", STANDALONE_X509); $manager = new MongoDB\Driver\Manager($dsn, array(), array("context" => $context)); $bulk = new MongoDB\Driver\BulkWrite(); $bulk->insert(array("very" => "important")); $manager->executeBulkWrite(NS, $bulk); $query = new MongoDB\Driver\Query(array("very" => "important")); $cursor = $manager->executeQuery(NS, $query); foreach($cursor as $document) { var_dump($document->very); } $command = new MongoDB\Driver\Command(array("drop" => COLLECTION_NAME)); $result = $manager->executeCommand(DATABASE_NAME, $command); } catch(Exception $e) { echo get_class($e), ": ", $e->getMessage(), "\n"; } ?> ===DONE=== --EXPECTF-- string(9) "important" ===DONE=== mongodb-1.1.5/tests/connect/standalone-x509-0002.phpt0000664000175000017500000000376612673034026021724 0ustar jmikolajmikola--TEST-- Connect to MongoDB with using X509 retrieving username from certificate (stream context) --SKIPIF-- --FILE-- array( "peer_name" => "server", "verify_peer" => true, "verify_peer_name" => true, "allow_self_signed" => false, "cafile" => $SSL_DIR . "/ca.pem", /* Defaults to openssl.cafile */ "capath" => $SSL_DIR, /* Defaults to openssl.capath */ "local_cert" => $SSL_DIR . "/client.pem", "passphrase" => "qwerty", "verify_depth" => 5, "ciphers" => "HIGH:!EXPORT:!aNULL@STRENGTH", "capture_peer_cert" => true, "capture_peer_cert_chain" => true, "SNI_enabled" => true, "disable_compression" => false, "peer_fingerprint" => strtolower("FC16D0861C31D29E90A8A5C832469AB10EE7F4DD"), ), ); $context = stream_context_create($opts); try { /* mongoc will pull the username of the certificate */ $parsed = parse_url(STANDALONE_X509); $dsn = sprintf("mongodb://%s:%d/%s?ssl=true&authMechanism=MONGODB-X509", $parsed["host"], $parsed["port"], DATABASE_NAME); $manager = new MongoDB\Driver\Manager($dsn, array(), array("context" => $context)); $bulk = new MongoDB\Driver\BulkWrite(); $bulk->insert(array("very" => "important")); $manager->executeBulkWrite(NS, $bulk); $query = new MongoDB\Driver\Query(array("very" => "important")); $cursor = $manager->executeQuery(NS, $query); foreach($cursor as $document) { var_dump($document->very); } $command = new MongoDB\Driver\Command(array("drop" => COLLECTION_NAME)); $result = $manager->executeCommand(DATABASE_NAME, $command); } catch(Exception $e) { echo get_class($e), ": ", $e->getMessage(), "\n"; } ?> ===DONE=== --EXPECTF-- string(9) "important" ===DONE=== mongodb-1.1.5/tests/connect/standalone-x509-0003.phpt0000664000175000017500000000246212673034026021715 0ustar jmikolajmikola--TEST-- Connect to MongoDB with using SSL and X.509 auth (SSL options) --SKIPIF-- --FILE-- "server", "verify_peer" => true, "verify_peer_name" => true, "allow_self_signed" => false, "cafile" => $SSL_DIR . "/ca.pem", /* Defaults to openssl.cafile */ "local_cert" => $SSL_DIR . "/client.pem", ); try { $dsn = sprintf("%s&ssl=true", STANDALONE_X509); $manager = new MongoDB\Driver\Manager($dsn, array(), $opts); $bulk = new MongoDB\Driver\BulkWrite(); $bulk->insert(array("very" => "important")); $manager->executeBulkWrite(NS, $bulk); $query = new MongoDB\Driver\Query(array("very" => "important")); $cursor = $manager->executeQuery(NS, $query); foreach($cursor as $document) { var_dump($document->very); } $command = new MongoDB\Driver\Command(array("drop" => COLLECTION_NAME)); $result = $manager->executeCommand(DATABASE_NAME, $command); } catch(Exception $e) { echo get_class($e), ": ", $e->getMessage(), "\n"; } ?> ===DONE=== --EXPECTF-- string(9) "important" ===DONE=== mongodb-1.1.5/tests/connect/standalone-x509-0004.phpt0000664000175000017500000000306712673034026021720 0ustar jmikolajmikola--TEST-- Connect to MongoDB with using X509 retrieving username from certificate (SSL options) --SKIPIF-- --FILE-- "server", "verify_peer" => true, "verify_peer_name" => true, "allow_self_signed" => false, "cafile" => $SSL_DIR . "/ca.pem", /* Defaults to openssl.cafile */ "capath" => $SSL_DIR, /* Defaults to openssl.capath */ "local_cert" => $SSL_DIR . "/client.pem", ); try { /* mongoc will pull the username of the certificate */ $parsed = parse_url(STANDALONE_X509); $dsn = sprintf("mongodb://%s:%d/%s?ssl=true&authMechanism=MONGODB-X509", $parsed["host"], $parsed["port"], DATABASE_NAME); $manager = new MongoDB\Driver\Manager($dsn, array(), $opts); $bulk = new MongoDB\Driver\BulkWrite(); $bulk->insert(array("very" => "important")); $manager->executeBulkWrite(NS, $bulk); $query = new MongoDB\Driver\Query(array("very" => "important")); $cursor = $manager->executeQuery(NS, $query); foreach($cursor as $document) { var_dump($document->very); } $command = new MongoDB\Driver\Command(array("drop" => COLLECTION_NAME)); $result = $manager->executeCommand(DATABASE_NAME, $command); } catch(Exception $e) { echo get_class($e), ": ", $e->getMessage(), "\n"; } ?> ===DONE=== --EXPECTF-- string(9) "important" ===DONE=== mongodb-1.1.5/tests/connect/standalone-x509-error-0001.phpt0000664000175000017500000000314412673034026023040 0ustar jmikolajmikola--TEST-- X509 connection should not reuse previous stream after an auth failure --SKIPIF-- --FILE-- insert(array("very" => "important")); $manager->executeBulkWrite(NS, $bulk); echo "Connected\n"; } catch(Exception $e) { echo get_class($e), ": ", $e->getMessage(), "\n"; } return $manager; } $SSL_DIR = realpath(__DIR__ . "/" . "./../../scripts/ssl/"); $opts = array( "peer_name" => "server", "verify_peer" => true, "verify_peer_name" => true, "allow_self_signed" => false, "cafile" => $SSL_DIR . "/ca.pem", /* Defaults to openssl.cafile */ "capath" => $SSL_DIR, /* Defaults to openssl.capath */ "local_cert" => $SSL_DIR . "/client.pem", ); /* Wrong username */ $parsed = parse_url(STANDALONE_X509); $dsn = sprintf("mongodb://username@%s:%d/%s?ssl=true&authMechanism=MONGODB-X509", $parsed["host"], $parsed["port"], DATABASE_NAME); $m1 = connect($dsn, $opts); $m2 = connect($dsn, $opts); echo "Both should have failed with auth failure - without reusing previous stream\n"; ?> ===DONE=== --EXPECTF-- MongoDB\Driver\Exception\AuthenticationException: auth failed MongoDB\Driver\Exception\AuthenticationException: auth failed Both should have failed with auth failure - without reusing previous stream ===DONE=== mongodb-1.1.5/tests/functional/cursor-001.phpt0000664000175000017500000000355012673034026021025 0ustar jmikolajmikola--TEST-- Sorting single field, ascending, using the Cursor Iterator --SKIPIF-- --FILE-- array('_id' => 0, 'username' => 1), 'sort' => array('username' => 1), 'limit' => 104, )); $cursor = $manager->executeQuery(NS, $query); foreach ($cursor as $document) { echo $document->username . "\n"; } ?> ===DONE=== --EXPECT-- aaliyah.kertzmann aaron89 abbott.alden abbott.flo abby76 abernathy.adrienne abernathy.audrey abner.kreiger aboehm abshire.icie abshire.jazlyn adams.delta adolph20 adonis.schamberger agleason ahartmann ahettinger akreiger al.cormier al97 albin95 alda.murray alden.blanda alessandra76 alex73 alexa01 alfred.ritchie alia07 alia72 alize.hegmann allie48 alta.sawayn alvena.pacocha alvis22 alycia48 amalia84 amely01 amos.corkery amos78 anahi95 anais.feest anais58 andreanne.steuber angela.dickinson angelina.bartoletti angelina31 aniyah.franecki annalise40 antoinette.gaylord antoinette.weissnat aoberbrunner apacocha apollich ara92 arch44 arely.ryan armstrong.clara armstrong.gordon arnold.kiehn arvel.hilll asatterfield aschuppe ashlynn71 ashlynn85 ashton.o'kon austen03 austen47 austin67 awintheiser awyman ayana.brakus bailey.mertz bailey.sarina balistreri.donald barrett.prohaska bartell.susie bashirian.lina bayer.ova baylee.maggio bbernier bblick beahan.oleta beatty.layne beatty.myrtis beau49 beaulah.mann bechtelar.nadia becker.theron beer.mossie beer.roselyn benedict.johnson berge.enoch bergnaum.roberto bernardo.mccullough bernardo52 bernhard.margaretta bernie.morissette bethel20 betty09 bins.aliyah bins.laisha bjori blanda.danielle blanda.irving ===DONE=== mongodb-1.1.5/tests/functional/cursorid-001.phpt0000664000175000017500000000143312673034026021340 0ustar jmikolajmikola--TEST-- Sorting single field, ascending, using the Cursor Iterator --SKIPIF-- --FILE-- array('_id' => 0, 'username' => 1), 'sort' => array('username' => 1), 'batchSize' => 11, 'limit' => 110, )); $cursor = $manager->executeQuery(NS, $query); $cursorid = $cursor->getId(); $s1 = (string)$cursorid; var_dump( $cursorid, $s1 ); var_dump($s1 > 0); ?> ===DONE=== --EXPECTF-- object(MongoDB\Driver\CursorId)#%d (%d) { ["id"]=> %s(%d) } string(%d) "%d" bool(true) ===DONE=== mongodb-1.1.5/tests/functional/phpinfo-1.phpt0000664000175000017500000000102512673034026021006 0ustar jmikolajmikola--TEST-- phpinfo() --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- %a mongodb mongodb support => enabled mongodb version => 1.%d.%d%S mongodb stability => %s libmongoc version => 1.%s libbson version => 1.%s Directive => Local Value => Master Value mongodb.debug => no value => no value %a ===DONE=== mongodb-1.1.5/tests/functional/phpinfo-2.phpt0000664000175000017500000000112212673034026021005 0ustar jmikolajmikola--TEST-- phpinfo() --INI-- mongodb.debug=stderr --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- %a mongodb mongodb support => enabled mongodb version => 1.%d.%d%S mongodb stability => %s libmongoc version => 1.%s libbson version => 1.%s Directive => Local Value => Master Value mongodb.debug => stdout => stderr %a ===DONE=== mongodb-1.1.5/tests/functional/query-sort-001.phpt0000664000175000017500000000343512673034026021644 0ustar jmikolajmikola--TEST-- Sorting single field, ascending --SKIPIF-- --FILE-- array('_id' => 0, 'username' => 1), 'sort' => array('username' => 1), "limit" => 100, )); $cursor = $manager->executeQuery(NS, $query); foreach ($cursor as $document) { echo $document->username . "\n"; } ?> ===DONE=== --EXPECT-- aaliyah.kertzmann aaron89 abbott.alden abbott.flo abby76 abernathy.adrienne abernathy.audrey abner.kreiger aboehm abshire.icie abshire.jazlyn adams.delta adolph20 adonis.schamberger agleason ahartmann ahettinger akreiger al.cormier al97 albin95 alda.murray alden.blanda alessandra76 alex73 alexa01 alfred.ritchie alia07 alia72 alize.hegmann allie48 alta.sawayn alvena.pacocha alvis22 alycia48 amalia84 amely01 amos.corkery amos78 anahi95 anais.feest anais58 andreanne.steuber angela.dickinson angelina.bartoletti angelina31 aniyah.franecki annalise40 antoinette.gaylord antoinette.weissnat aoberbrunner apacocha apollich ara92 arch44 arely.ryan armstrong.clara armstrong.gordon arnold.kiehn arvel.hilll asatterfield aschuppe ashlynn71 ashlynn85 ashton.o'kon austen03 austen47 austin67 awintheiser awyman ayana.brakus bailey.mertz bailey.sarina balistreri.donald barrett.prohaska bartell.susie bashirian.lina bayer.ova baylee.maggio bbernier bblick beahan.oleta beatty.layne beatty.myrtis beau49 beaulah.mann bechtelar.nadia becker.theron beer.mossie beer.roselyn benedict.johnson berge.enoch bergnaum.roberto bernardo.mccullough bernardo52 bernhard.margaretta bernie.morissette bethel20 betty09 bins.aliyah ===DONE=== mongodb-1.1.5/tests/functional/query-sort-002.phpt0000664000175000017500000000320112673034026021634 0ustar jmikolajmikola--TEST-- Sorting single field, descending --SKIPIF-- --FILE-- array('_id' => 0, 'username' => 1), 'sort' => array('username' => -1), 'limit' => 100, )); $cursor = $manager->executeQuery(NS, $query); foreach ($cursor as $document) { echo $document->username . "\n"; } ?> ===DONE=== --EXPECT-- zulauf.amaya zstanton zoe41 zieme.noemi ziemann.webster zheathcote zella78 zboyle zachery33 yyost ywyman ywiza ypredovic yost.magali yost.ari ylarkin yklein yhudson yfritsch ycole yasmine.lowe yasmin55 xrodriguez xkohler xhermann xgutmann xgibson xcassin wwilkinson wunsch.mose wschimmel wschaefer wpacocha wolff.caroline wkertzmann wiza.carmel witting.walker witting.chris wisozk.cortez winnifred08 wilson.white willms.amari will.lamont will.jerod will.edwina wilfred.feil wilderman.sophia wiegand.blanche west.jude west.cristobal weimann.tillman webster70 webster48 watson70 warren.feest walton33 walter.norval walter.lester walsh.vincenza walker.alec wade91 vwaters vvolkman vschulist vrolfson vpfeffer vorn von.britney vivianne.macejkovic veum.tyrell vesta.ritchie verda93 vena.schumm velma37 velda.wehner veffertz vdickinson vconn vbraun vborer vbins vandervort.ezekiel van.ruecker uzieme uwisoky usmith uschumm uschmeler urban24 upton.zackery unique.pagac una.larkin umraz ullrich.layne ulises44 ulises.beatty ulesch ukovacek ujenkins uhansen ===DONE=== mongodb-1.1.5/tests/functional/query-sort-003.phpt0000664000175000017500000003144012673034026021643 0ustar jmikolajmikola--TEST-- Sorting single field, ascending, using the Cursor Iterator --SKIPIF-- --FILE-- array('_id' => 0, 'username' => 1), 'sort' => array('username' => 1), )); var_dump($query); $cursor = $manager->executeQuery(NS, $query); var_dump(get_class($cursor)); foreach ($cursor as $document) { echo $document->username . "\n"; } ?> ===DONE=== --EXPECTF-- object(MongoDB\Driver\Query)#%d (%d) { ["query"]=> object(stdClass)#%d (2) { ["$orderby"]=> object(stdClass)#%d (1) { ["username"]=> int(1) } ["$query"]=> object(stdClass)#%d (%d) { } } ["selector"]=> object(stdClass)#%d (2) { ["_id"]=> int(0) ["username"]=> int(1) } ["flags"]=> int(0) ["skip"]=> int(0) ["limit"]=> int(0) ["batch_size"]=> int(0) ["readConcern"]=> NULL } string(21) "MongoDB\Driver\Cursor" aaliyah.kertzmann aaron89 abbott.alden abbott.flo abby76 abernathy.adrienne abernathy.audrey abner.kreiger aboehm abshire.icie abshire.jazlyn adams.delta adolph20 adonis.schamberger agleason ahartmann ahettinger akreiger al.cormier al97 albin95 alda.murray alden.blanda alessandra76 alex73 alexa01 alfred.ritchie alia07 alia72 alize.hegmann allie48 alta.sawayn alvena.pacocha alvis22 alycia48 amalia84 amely01 amos.corkery amos78 anahi95 anais.feest anais58 andreanne.steuber angela.dickinson angelina.bartoletti angelina31 aniyah.franecki annalise40 antoinette.gaylord antoinette.weissnat aoberbrunner apacocha apollich ara92 arch44 arely.ryan armstrong.clara armstrong.gordon arnold.kiehn arvel.hilll asatterfield aschuppe ashlynn71 ashlynn85 ashton.o'kon austen03 austen47 austin67 awintheiser awyman ayana.brakus bailey.mertz bailey.sarina balistreri.donald barrett.prohaska bartell.susie bashirian.lina bayer.ova baylee.maggio bbernier bblick beahan.oleta beatty.layne beatty.myrtis beau49 beaulah.mann bechtelar.nadia becker.theron beer.mossie beer.roselyn benedict.johnson berge.enoch bergnaum.roberto bernardo.mccullough bernardo52 bernhard.margaretta bernie.morissette bethel20 betty09 bins.aliyah bins.laisha bjori blanda.danielle blanda.irving blanda.ruthe blaze.miller block.kasandra block.toby bmccullough botsford.edwardo botsford.jennie boyd.balistreri boyer.khalid boyle.franco bpaucek bpurdy bradford.heidenreich brannon24 braun.adaline braun.jeanie breanne.schmeler breitenberg.demarco brennan.emmerich bret57 broderick53 brooklyn22 bruecker bstamm buckridge.julius buddy42 bwalker camilla20 cara.bechtelar carlotta.kreiger carolyn09 carolyne63 carroll.emmalee cartwright.garland casimir.keebler casper.eldred casper.juliana casper38 cassin.carmel cassin.krystel catherine.hilll cathrine.gislason cbartoletti cbecker cbednar cbreitenberg cecelia.schoen celestine97 cfriesen cgreenfelder chad.kuphal chance.conroy chasity63 chet.pacocha christina.simonis chyna05 citlalli41 ckertzmann clarabelle65 clementine.grimes clotilde39 cnikolaus cole.alice coleman55 collier.sage collins.skylar columbus78 connelly.josefina conner.doyle coralie47 cordelia25 corkery.arch cormier.adriana cormier.amy cormier.landen cormier.vida cory76 cpaucek cprice craig93 creola.emard creola88 crona.jaclyn cronin.clint crooks.josh crystel24 csipes cummings.frederic cwaelchi cwest cwhite cwolf cydney.hayes dahlia.white daisy.johns dakota.bednar dakota.wiza dallas.marquardt dante.shields darwin.howe dave46 davis.bennett davis.solon dayne.padberg dayton03 delaney91 delbert.auer delia.lindgren deontae36 dereck.ward derek.bahringer derek79 deven.spinka devon34 dgottlieb dhudson dickinson.ashleigh dillan66 djerde dock.bednar dolly.beer donnie.langosh dorothy67 dorthy.legros doyle.nelle drippin dubuque.brooklyn dubuque.cordia dvandervort dwiegand dwolf earlene.marvin earline.baumbach easter73 eauer ebert.cordie ebony.williamson ebony59 edgar33 edgardo.gorczany edibbert effertz.mateo effie.keeling efren31 egrimes ehirthe ehuel ehuels eino23 ekoelpin eldora.steuber eldred65 elenor33 elesch eli.mann elisabeth95 eliseo49 ella.roberts ellen.krajcik ellen12 elliot.kling elliot.weissnat ellis37 elsie.kuhic elva.baumbach elvis45 emelia.ortiz emerald.shanahan emerson07 emie.schneider emilio.crona emily91 emmalee.waters enid57 enid78 enoch.hilll enola.rath ephraim76 erdman.ethyl erdman.niko eriberto.russel erik04 erika74 ernser.addison ernser.geovany ervin.carter espinka ethan.daugherty ethel56 ethelyn46 ethyl68 ettie49 eulah49 fabian55 fadel.trevion fae00 fahey.rosalee farrell.asha farrell.lessie fbraun feeney.angelica feeney.elizabeth feeney.nathanial feil.rae ferdman ferry.eusebio fherman filomena18 finn.torphy flavie41 florida.o'hara ford85 fosinski frami.bulah franecki.rosetta fred35 freda25 frederik.stracke fsporer fstokes fturner gabriel.mccullough gardner.jacobson garnet.oberbrunner garry.windler gaylord.myrtis gblock gbrakus georgette.mueller geovanni.jones geovany07 german.leffler german40 ggislason gia15 gibson.amiya giovani.langworth giovanna.hickle giovanny.haley gislason.mae gisselle.jacobs gladyce88 glang gottlieb.jerry goyette.roman gparker gprosacco gracie.mcdermott graciela.jacobson grayson78 greenfelder.amya greenfelder.larry greenfelder.ozella gretchen19 gretchen38 greynolds greyson63 grimes.andreane gulgowski.allie gusikowski.aliyah gutkowski.laron gwunsch haag.alaina hackett.alycia hadley.abernathy hailee01 hal67 haley.grace haley.krystel haley.lauretta halvorson.bulah hammes.dimitri hand.lauren hand.tiana hansen.vanessa harber.larissa harber.vicenta harris.kailey hartmann.dedrick harvey.hillard haven13 hayes.delores hayley08 hazle21 hazle43 heathcote.ashly hegmann.sallie heidenreich.julia helene.o'connell henriette21 herman.sanford herzog.eileen hessel.barry hflatley hhackett hhyatt hickle.isabell hirthe.bryana hirthe.letitia hirthe.reymundo hmarvin hoeger.anastacio hollie29 howe.abagail howell.daugherty hquigley hrodriguez hspinka hstamm htowne hudson.bernie hudson.deion huels.alfred huels.enid hugh22 humberto98 hvandervort hyatt.astrid hyatt.soledad iabernathy idaugherty idella50 idonnelly ifeil ileuschke imuller ipredovic irwin.gutkowski irwin31 isabell95 isabella.parisian isac13 isac67 isaiah47 isaiah50 isaias90 isobel.mraz ivy73 izabella.hermann jacobs.carmela jada.romaguera jadon.reinger jailyn62 jalon90 jamaal.cassin jamarcus.weissnat janelle93 janice.walker jannie71 jaquan94 jaqueline.o'kon jarod94 jarrod.lindgren jasmin.ruecker javier.volkman javier13 javier62 jayda.d'amore jazmyne63 jborer jeanette45 jedidiah.hyatt jefferey02 jenkins.letha jerald.konopelski jeremy.o'keefe jessika.schmeler jessy16 jett00 jfeest jheaney jherzog jlebsack jlockman jo'hara jodie.casper johnnie66 johnston.brooklyn jonas97 jones.jazmyn jordan.turner joshua.mraz josiah59 joyce.casper jruecker jschamberger jschinner jthompson jtowne jude.jakubowski jude92 juliana.witting juliet55 june.runolfsson justina63 jwindler kadams kadin.mayer kaelyn05 kaelyn88 kamille.watsica kamron88 karson.mante kasey.abshire kassandra.reilly katheryn.walsh kathlyn02 kathryne.boehm kattie12 kaya24 kayleigh62 kbeahan kdicki keagan.hirthe keanu21 keanu42 keebler.rupert keeling.sydnee keira.dach kelly.konopelski kelvin.jakubowski kerluke.hiram kernser keshawn.boyle kessler.marisol keyon.gaylord keyon65 kherman khills khudson kiley63 kip12 kirk40 kirstin.cruickshank klarson kleuschke kling.laila klocko.filiberto kmohr ko'keefe koch.emmett koch.sophia koelpin.yoshiko krystel.stark kturcotte kub.marcel kuhic.hattie kuhlman.noel kuphal.ahmed kutch.chase kutch.madonna kutch.pasquale kuvalis.nicolette lane05 larkin.lawson larue.schuster laurel35 laurel72 laurence28 lauryn.beer lbode lbradtke leanne.cronin leannon.zander lebsack.harmony ledner.finn leif52 leilani73 lemke.ernestina lempi56 leopold69 lesch.delfina lesch.edna lesch.nyah leuschke.erika lexie.bernier lexie65 lgrady lillian50 lilliana.schaden lily.hansen lind.dane lloyd60 lmckenzie lnicolas london07 lonnie.little lonnie10 loraine.hammes lorna31 louisa76 lquitzon lubowitz.colleen lubowitz.jazmyne lucas.ferry luciano79 lucienne13 lucio.huel lucio20 luella.deckow lullrich luther.lesch mac.hermann macey95 macie.corwin macy.greenholt maddison66 madilyn.wyman madisyn51 madyson.johns maeve.raynor maggio.kayli maia14 mante.ashlee mante.maymie marc97 marcel56 marco.gerlach mariana.sipes marietta.swift marina.mayert marion15 marion35 marjolaine45 mark.casper marks.trace marlen34 marlene95 marley.sipes marvin.ivory maryjane.kutch maudie25 mayer.tanner mccullough.vella mcdermott.kaitlyn mckenzie.maximus mdare meaghan89 melisa61 metz.elmer metz.ima michaela.wolf miles.pollich milford39 milford40 mills.emmanuel mills.rickey miracle53 misty.boyer mitchell.delta mitchell.rafael mohammad.gorczany mohammed.lemke mohr.kylee mollie.deckow monroe.o'keefe monserrate.leannon monserrate.nikolaus monty.mills morar.aniya mosciski.alanis mraz.marcelina mrunte mtoy mueller.woodrow muller.akeem murazik.maximillia mwalter mylene.rogahn myra43 myron.bechtelar mzemlak mzieme nash88 nasir24 natalia66 nathanial37 nayeli.vandervort ndouglas neal.hand neichmann neil.gorczany nellie23 ngoldner nhaag nharber nharris nicolas.melyssa nicolas.wendy nikita.romaguera nikko.langosh nikolas.lang nikolas78 nikolaus.celestino njacobs nkshlerin noah.blick nolan.nora nolan.zachariah nolan56 norma46 novella67 npurdy nrath nrowe nstamm nward o'conner.arthur obie.weissnat oboyer octavia36 oda.robel odare odell96 ogulgowski ohaley ohowe okuneva.ebba olga.mertz olga.waelchi olin13 oliver.reichert olson.dedrick olynch omarvin omer.kirlin ondricka.alexzander ondricka.joy orion.quigley orn.katelyn orval95 oswaldo.kunze otreutel owehner owen82 pacocha.quentin pagac.coleman paige.murphy parisian.dena parker.ellie patience65 patricia.macejkovic pattie.waters pattie97 paul.hayes paula.fahey paxton73 pbotsford pconroy pcruickshank pdach perry63 pfannerstill.erna pframi phahn philpert phodkiewicz phoebe.crona phuel pierre.grant plesch pollich.danika polson powlowski.alfredo ppurdy price49 prohaska.ransom prudence76 prussel pschowalter pwaters pwatsica pwisozk qarmstrong qbatz qgislason qkunze qmayert qo'hara qpowlowski qromaguera qryan qschiller qschneider queen75 queenie33 quitzon.greyson quitzon.maxime rachel45 raphaelle55 ratke.aurelia rau.brent raven.walter raven.ziemann raymundo.ferry raynor.wilmer rdickens regan86 reginald.gulgowski reichert.margaretta reinger.johnathan remington.russel renner.lucius rey29 rice.ronaldo rico71 river66 rkoelpin rmayer robel.chance rocky.hoeger rodger.raynor rodolfo.effertz rohan.harmon rolando38 rolfson.jaren rosalee52 rosemarie.conn rosenbaum.elisa rosetta45 rowe.erik rschowalter rubie.hyatt russel64 rutherford.dawn sabina11 samara90 sarina.bednar savannah89 savion82 sawayn.catharine sawayn.pink sbailey schamberger.marcelle schiller.kameron schimmel.mavis schimmel.russell schmeler.dillon schmeler.flo schmidt.elwyn schmitt.magali schneider.rita schowalter.abbigail schroeder.zoey schulist.angelo schumm.carley schumm.danielle sebert selina.thiel sferry shaina.emard shanie.murazik sheathcote shegmann shields.bethany shoeger shyann28 sienna53 sigmund.schinner simeon.nader skihn skiles.darrin skye.jast skyla.friesen smith.nico so'kon soledad.connelly sonia05 sorn spencer.bessie spencer.darrel sschumm ssteuber stacy.leffler stark.vladimir stehr.odell stella.schowalter stracke.dakota streich.abdiel stroman.rae susanna55 swyman sylvia82 tabitha.mohr talon74 tanya65 tatum.harvey tbarrows tcole terry.corene terry.florian tessie.stroman tgrady thalia22 theo62 theodore55 theresia68 theron10 tkonopelski tlind tomas04 toni57 toy.deshawn trace03 tressa.price tressie47 treutel.evert treutel.minnie trolfson tromp.kaleigh trudie09 trutherford tsatterfield tstamm turcotte.armand turner.considine twila75 uabshire uchamplin udach ugusikowski uhansen ujenkins ukovacek ulesch ulises.beatty ulises44 ullrich.layne umraz una.larkin unique.pagac upton.zackery urban24 uschmeler uschumm usmith uwisoky uzieme van.ruecker vandervort.ezekiel vbins vborer vbraun vconn vdickinson veffertz velda.wehner velma37 vena.schumm verda93 vesta.ritchie veum.tyrell vivianne.macejkovic von.britney vorn vpfeffer vrolfson vschulist vvolkman vwaters wade91 walker.alec walsh.vincenza walter.lester walter.norval walton33 warren.feest watson70 webster48 webster70 weimann.tillman west.cristobal west.jude wiegand.blanche wilderman.sophia wilfred.feil will.edwina will.jerod will.lamont willms.amari wilson.white winnifred08 wisozk.cortez witting.chris witting.walker wiza.carmel wkertzmann wolff.caroline wpacocha wschaefer wschimmel wunsch.mose wwilkinson xcassin xgibson xgutmann xhermann xkohler xrodriguez yasmin55 yasmine.lowe ycole yfritsch yhudson yklein ylarkin yost.ari yost.magali ypredovic ywiza ywyman yyost zachery33 zboyle zella78 zheathcote ziemann.webster zieme.noemi zoe41 zstanton zulauf.amaya ===DONE=== mongodb-1.1.5/tests/functional/query-sort-004.phpt0000664000175000017500000000253212673034026021644 0ustar jmikolajmikola--TEST-- Sort query option is always serialized as a BSON document --SKIPIF-- --FILE-- insert(array('_id' => $i, '0' => 4 - $i)); } $writeResult = $manager->executeBulkWrite(NS, $bulkWrite); printf("Inserted: %d\n", $writeResult->getInsertedCount()); $query = new MongoDB\Driver\Query(array(), array( 'sort' => array('0' => 1), )); var_dump($query); $cursor = $manager->executeQuery(NS, $query); /* Numeric keys of stdClass instances cannot be directly accessed, so ensure the * document is decoded as a PHP array. */ $cursor->setTypeMap(array('root' => 'array')); foreach ($cursor as $document) { echo $document['0'] . "\n"; } ?> ===DONE=== --EXPECTF-- Inserted: 5 object(MongoDB\Driver\Query)#%d (%d) { ["query"]=> object(stdClass)#%d (2) { ["$orderby"]=> object(stdClass)#%d (1) { [0]=> int(1) } ["$query"]=> object(stdClass)#%d (0) { } } ["selector"]=> NULL ["flags"]=> int(0) ["skip"]=> int(0) ["limit"]=> int(0) ["batch_size"]=> int(0) ["readConcern"]=> NULL } 0 1 2 3 4 ===DONE=== mongodb-1.1.5/tests/manager/manager-ctor-001.phpt0000664000175000017500000000046612673034026021342 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::__construct() with default URI --SKIPIF-- --FILE-- ===DONE=== --EXPECT-- ===DONE=== mongodb-1.1.5/tests/manager/manager-ctor-002.phpt0000664000175000017500000000047012673034026021336 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::__construct() with URI --SKIPIF-- --FILE-- ===DONE=== --EXPECT-- ===DONE=== mongodb-1.1.5/tests/manager/manager-ctor_error-001.phpt0000664000175000017500000000122512673034026022545 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::__construct(): too many arguments --SKIPIF-- --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException MongoDB\Driver\Manager::__construct() expects at most 3 parameters, 4 given ===DONE=== mongodb-1.1.5/tests/manager/manager-ctor_error-002.phpt0000664000175000017500000000101612673034026022544 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::__construct(): invalid URI --SKIPIF-- --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Failed to parse MongoDB URI: 'not a valid connection string' ===DONE=== mongodb-1.1.5/tests/manager/manager-ctor_error-003.phpt0000664000175000017500000000226512673034026022554 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::__construct(): invalid read preference --SKIPIF-- --FILE-- 'nothing')); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; echo throws(function() { $manager = new MongoDB\Driver\Manager(STANDALONE . '/?readPreference=primary', array('readPreferenceTags' => array(array()))); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; ?> ===DONE=== --EXPECTF-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Failed to parse MongoDB URI: '%s/?readPreference=primary&readPreferenceTags=dc:ny' OK: Got MongoDB\Driver\Exception\InvalidArgumentException Unsupported readPreference value: 'nothing' OK: Got MongoDB\Driver\Exception\InvalidArgumentException Primary read preference mode conflicts with tags ===DONE=== mongodb-1.1.5/tests/manager/manager-ctor_error-004.phpt0000664000175000017500000000520312673034026022550 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::__construct(): invalid write concern --SKIPIF-- --FILE-- true)); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; echo throws(function() { $manager = new MongoDB\Driver\Manager(STANDALONE . '/?w=0', array('journal' => true)); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; echo throws(function() { $manager = new MongoDB\Driver\Manager(STANDALONE . '/?journal=true', array('w' => -1)); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; echo throws(function() { $manager = new MongoDB\Driver\Manager(STANDALONE . '/?journal=true', array('w' => 0)); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; echo throws(function() { $manager = new MongoDB\Driver\Manager(STANDALONE, array('w' => -1, 'journal' => true)); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; echo throws(function() { $manager = new MongoDB\Driver\Manager(STANDALONE, array('w' => 0, 'journal' => true)); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; echo throws(function() { $manager = new MongoDB\Driver\Manager(STANDALONE, array('w' => -2)); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; ?> ===DONE=== --EXPECTF-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Failed to parse MongoDB URI: '%s/?w=-1&journal=true' OK: Got MongoDB\Driver\Exception\InvalidArgumentException Failed to parse MongoDB URI: '%s/?w=0&journal=true' OK: Got MongoDB\Driver\Exception\InvalidArgumentException Journal conflicts with w value: -1 OK: Got MongoDB\Driver\Exception\InvalidArgumentException Journal conflicts with w value: 0 OK: Got MongoDB\Driver\Exception\InvalidArgumentException Journal conflicts with w value: -1 OK: Got MongoDB\Driver\Exception\InvalidArgumentException Journal conflicts with w value: 0 OK: Got MongoDB\Driver\Exception\InvalidArgumentException Journal conflicts with w value: -1 OK: Got MongoDB\Driver\Exception\InvalidArgumentException Journal conflicts with w value: 0 OK: Got MongoDB\Driver\Exception\InvalidArgumentException Unsupported w value: -2 ===DONE=== mongodb-1.1.5/tests/manager/manager-debug-001.phpt0000664000175000017500000000214212673034026021452 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager: Writing debug log files --SKIPIF-- --FILE-- $name)); $bulk = new MongoDB\Driver\BulkWrite(); $bulk->insert(array('_id' => 1, 'x' => 1)); $result = $manager->executeBulkWrite(NS, $bulk); foreach(glob($name."/*") as $file); $content = file($file); unlink($file); rmdir($name); echo $content[0]; foreach($content as $line) { if (strpos($line, "mongoc_bulk_operation_execute")) { echo $line; } } ?> ===DONE=== --EXPECTF-- [%s] PHONGO: DEBUG > Creating Manager, phongo-1.%d.%d%S[%s] - mongoc-1.%s(%s), libbson-1.%s(%s), php-%s [%s] mongoc: TRACE > ENTRY: mongoc_bulk_operation_execute():%d [%s] mongoc: TRACE > EXIT: mongoc_bulk_operation_execute():%d ===DONE=== mongodb-1.1.5/tests/manager/manager-debug-002.phpt0000664000175000017500000000142112673034026021452 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager: mongodb.debug=stderr --SKIPIF-- --INI-- mongodb.debug=stderr --FILE-- insert(array('_id' => 1, 'x' => 1)); $result = $manager->executeBulkWrite(NS, $bulk); ini_set("mongodb.debug", "off"); ?> ===DONE=== --EXPECTF-- %a [%s] PHONGO: DEBUG > Creating Manager, phongo-1.%d.%d%S[%s] - mongoc-1.%s(%s), libbson-1.%s(%s), php-%s %a [%s] PHONGO: DEBUG > Connecting to '%s:%d[mongodb://%s:%d]' %a ===DONE=== mongodb-1.1.5/tests/manager/manager-debug-003.phpt0000664000175000017500000000142012673034026021452 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager: mongodb.debug=stdout --SKIPIF-- --INI-- mongodb.debug=stdout --FILE-- insert(array('_id' => 1, 'x' => 1)); $result = $manager->executeBulkWrite(NS, $bulk); ini_set("mongodb.debug", "off"); ?> ===DONE=== --EXPECTF-- %a [%s] PHONGO: TRACE > ENTRY: php_phongo_make_mongo_client():%d [%s] PHONGO: DEBUG > Creating Manager, phongo-1.%d.%d%S[%s] - mongoc-1.%s(%s), libbson-1.%s(%s), php-%s %a ===DONE=== mongodb-1.1.5/tests/manager/manager-destruct-001.phpt0000664000175000017500000000203612673034026022223 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager destruct should not free streams that are still in use --SKIPIF-- --INI-- ignore_repeated_errors=1 --FILE-- insert(array('_id' => 1)); $writeResult = $manager1->executeBulkWrite(NS, $bulk); printf("Inserted: %d\n", $writeResult->getInsertedCount()); $bulk = new MongoDB\Driver\BulkWrite(); $bulk->insert(array('_id' => 2)); $writeResult = $manager2->executeBulkWrite(NS, $bulk); printf("Inserted: %d\n", $writeResult->getInsertedCount()); $manager2 = null; $bulk = new MongoDB\Driver\BulkWrite(); $bulk->insert(array('_id' => 3)); $writeResult = $manager1->executeBulkWrite(NS, $bulk); printf("Inserted: %d\n", $writeResult->getInsertedCount()); ?> ===DONE=== --EXPECT-- Inserted: 1 Inserted: 1 Inserted: 1 ===DONE=== mongodb-1.1.5/tests/manager/manager-executeBulkWrite-001.phpt0000664000175000017500000000241512673034026023662 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::executeBulkWrite() --SKIPIF-- --FILE-- insert(array('_id' => 1, 'x' => 1)); $bulk->insert(array('_id' => 2, 'x' => 2)); $bulk->update(array('x' => 2), array('$set' => array('x' => 1)), array("limit" => 1, "upsert" => false)); $bulk->update(array('_id' => 3), array('$set' => array('x' => 3)), array("limit" => 1, "upsert" => true)); $bulk->delete(array('x' => 1), array("limit" => 1)); $result = $manager->executeBulkWrite(NS, $bulk); echo "\n===> WriteResult\n"; printWriteResult($result); echo "\n===> Collection\n"; $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query(array())); var_dump(iterator_to_array($cursor)); ?> ===DONE=== --EXPECTF-- ===> WriteResult server: %s:%d insertedCount: 2 matchedCount: 1 modifiedCount: 1 upsertedCount: 1 deletedCount: 1 upsertedId[3]: int(3) ===> Collection array(2) { [0]=> object(stdClass)#%d (2) { ["_id"]=> int(2) ["x"]=> int(1) } [1]=> object(stdClass)#%d (2) { ["_id"]=> int(3) ["x"]=> int(3) } } ===DONE=== mongodb-1.1.5/tests/manager/manager-executeBulkWrite-002.phpt0000664000175000017500000000307512673034026023666 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::executeBulkWrite() with upserted ids --SKIPIF-- --FILE-- false]); $bulk->update(array('x' => 'foo'), array('$set' => array('y' => 'foo')), array('upsert' => true)); $bulk->update(array('x' => 'bar'), array('$set' => array('y' => 'bar')), array('upsert' => true)); $bulk->update(array('x' => 'foo'), array('$set' => array('y' => 'bar'))); $result = $manager->executeBulkWrite(NS, $bulk); echo "\n===> WriteResult\n"; printWriteResult($result); echo "\n===> Collection\n"; $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query(array())); var_dump(iterator_to_array($cursor)); ?> ===DONE=== --EXPECTF-- ===> WriteResult server: %s:%d insertedCount: 0 matchedCount: 1 modifiedCount: 1 upsertedCount: 2 deletedCount: 0 upsertedId[0]: object(%s\ObjectID)#%d (%d) { ["oid"]=> string(24) "%s" } upsertedId[1]: object(%s\ObjectID)#%d (%d) { ["oid"]=> string(24) "%s" } ===> Collection array(2) { [0]=> object(stdClass)#%d (3) { ["_id"]=> object(%s\ObjectID)#%d (%d) { ["oid"]=> string(24) "%s" } ["x"]=> string(3) "foo" ["y"]=> string(3) "bar" } [1]=> object(stdClass)#%d (3) { ["_id"]=> object(%s\ObjectID)#%d (%d) { ["oid"]=> string(24) "%s" } ["x"]=> string(3) "bar" ["y"]=> string(3) "bar" } } ===DONE=== mongodb-1.1.5/tests/manager/manager-executeBulkWrite-003.phpt0000664000175000017500000000210712673034026023662 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::executeBulkWrite() delete one document --SKIPIF-- --FILE-- insert(array('_id' => 1, 'x' => 1)); $bulk->insert(array('_id' => 2, 'x' => 1)); $manager->executeBulkWrite(NS, $bulk); $bulk = new MongoDB\Driver\BulkWrite(); $bulk->delete(array('x' => 1), array('limit' => 1)); $result = $manager->executeBulkWrite(NS, $bulk); echo "\n===> WriteResult\n"; printWriteResult($result); echo "\n===> Collection\n"; $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query(array())); var_dump(iterator_to_array($cursor)); ?> ===DONE=== --EXPECTF-- ===> WriteResult server: %s:%d insertedCount: 0 matchedCount: 0 modifiedCount: 0 upsertedCount: 0 deletedCount: 1 ===> Collection array(1) { [0]=> object(stdClass)#%d (2) { ["_id"]=> int(2) ["x"]=> int(1) } } ===DONE=== mongodb-1.1.5/tests/manager/manager-executeBulkWrite-004.phpt0000664000175000017500000000176612673034026023675 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::executeBulkWrite() delete multiple documents --SKIPIF-- --FILE-- insert(array('_id' => 1, 'x' => 1)); $bulk->insert(array('_id' => 2, 'x' => 1)); $manager->executeBulkWrite(NS, $bulk); $bulk = new MongoDB\Driver\BulkWrite(); $bulk->delete(array('x' => 1), array('limit' => 0)); $result = $manager->executeBulkWrite(NS, $bulk); echo "\n===> WriteResult\n"; printWriteResult($result); echo "\n===> Collection\n"; $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query(array())); var_dump(iterator_to_array($cursor)); ?> ===DONE=== --EXPECTF-- ===> WriteResult server: %s:%d insertedCount: 0 matchedCount: 0 modifiedCount: 0 upsertedCount: 0 deletedCount: 2 ===> Collection array(0) { } ===DONE=== mongodb-1.1.5/tests/manager/manager-executeBulkWrite-005.phpt0000664000175000017500000000157412673034026023673 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::executeBulkWrite() insert one document --SKIPIF-- --FILE-- insert(array('_id' => 1, 'x' => 1)); $result = $manager->executeBulkWrite(NS, $bulk); echo "\n===> WriteResult\n"; printWriteResult($result); echo "\n===> Collection\n"; $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query(array())); var_dump(iterator_to_array($cursor)); ?> ===DONE=== --EXPECTF-- ===> WriteResult server: %s:%d insertedCount: 1 matchedCount: 0 modifiedCount: 0 upsertedCount: 0 deletedCount: 0 ===> Collection array(1) { [0]=> object(stdClass)#%d (2) { ["_id"]=> int(1) ["x"]=> int(1) } } ===DONE=== mongodb-1.1.5/tests/manager/manager-executeBulkWrite-006.phpt0000664000175000017500000000364712673034026023677 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::executeBulkWrite() insert one document (with embedded) --SKIPIF-- --FILE-- addAddress($sunnyvale); $hannes->addAddress($kopavogur); $mikola = new Person("Jeremy", 21); $michigan = new Address(48169, "USA"); $hannes->addFriend($mikola); $bulk = new MongoDB\Driver\BulkWrite(); $bulk->insert($hannes); $result = $manager->executeBulkWrite(NS, $bulk); echo "\n===> WriteResult\n"; printWriteResult($result); echo "\n===> Collection\n"; $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query(array())); foreach($cursor as $object) { var_dump($object); } ?> ===DONE=== --EXPECTF-- ===> WriteResult server: %s:%d insertedCount: 1 matchedCount: 0 modifiedCount: 0 upsertedCount: 0 deletedCount: 0 ===> Collection object(Person)#%d (5) { ["name":protected]=> string(6) "Hannes" ["age":protected]=> int(42) ["addresses":protected]=> array(2) { [0]=> object(Address)#%d (2) { ["zip":protected]=> int(94086) ["country":protected]=> string(3) "USA" } [1]=> object(Address)#%d (2) { ["zip":protected]=> int(200) ["country":protected]=> string(7) "Iceland" } } ["friends":protected]=> array(1) { [0]=> object(Person)#%d (5) { ["name":protected]=> string(6) "Jeremy" ["age":protected]=> int(21) ["addresses":protected]=> array(0) { } ["friends":protected]=> array(0) { } ["secret":protected]=> string(4) "none" } } ["secret":protected]=> string(4) "none" } ===DONE=== mongodb-1.1.5/tests/manager/manager-executeBulkWrite-007.phpt0000664000175000017500000000216312673034026023670 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::executeBulkWrite() update one document with no upsert --SKIPIF-- --FILE-- insert(array('_id' => 1, 'x' => 1)); $manager->executeBulkWrite(NS, $bulk); $bulk = new MongoDB\Driver\BulkWrite(); $bulk->update( array('_id' => 1), array('$set' => array('x' => 2)), array('multi' => false, 'upsert' => false) ); $result = $manager->executeBulkWrite(NS, $bulk); echo "\n===> WriteResult\n"; printWriteResult($result); echo "\n===> Collection\n"; $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query(array())); var_dump(iterator_to_array($cursor)); ?> ===DONE=== --EXPECTF-- ===> WriteResult server: %s:%d insertedCount: 0 matchedCount: 1 modifiedCount: 1 upsertedCount: 0 deletedCount: 0 ===> Collection array(1) { [0]=> object(stdClass)#%d (2) { ["_id"]=> int(1) ["x"]=> int(2) } } ===DONE=== mongodb-1.1.5/tests/manager/manager-executeBulkWrite-008.phpt0000664000175000017500000000274712673034026023701 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::executeBulkWrite() update multiple documents with no upsert --SKIPIF-- --FILE-- insert(array('_id' => 1, 'x' => 1)); $bulk->insert(array('_id' => 2, 'x' => 1)); $bulk->insert(array('_id' => 3, 'x' => 3)); $manager->executeBulkWrite(NS, $bulk); $bulk = new MongoDB\Driver\BulkWrite(); $bulk->update( array('x' => 1), array('$set' => array('x' => 2)), array('multi' => true, 'upsert' => false) ); $result = $manager->executeBulkWrite(NS, $bulk); echo "\n===> WriteResult\n"; printWriteResult($result); echo "\n===> Collection\n"; $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query(array())); var_dump(iterator_to_array($cursor)); ?> ===DONE=== --EXPECTF-- ===> WriteResult server: %s:%d insertedCount: 0 matchedCount: 2 modifiedCount: 2 upsertedCount: 0 deletedCount: 0 ===> Collection array(3) { [0]=> object(stdClass)#%d (2) { ["_id"]=> int(1) ["x"]=> int(2) } [1]=> object(stdClass)#%d (2) { ["_id"]=> int(2) ["x"]=> int(2) } [2]=> object(stdClass)#%d (2) { ["_id"]=> int(3) ["x"]=> int(3) } } ===DONE=== mongodb-1.1.5/tests/manager/manager-executeBulkWrite-009.phpt0000664000175000017500000000175712673034026023702 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::executeBulkWrite() update one document with upsert --SKIPIF-- --FILE-- update( array('_id' => 1), array('$set' => array('x' => 1)), array('multi' => false, 'upsert' => true) ); $result = $manager->executeBulkWrite(NS, $bulk); echo "\n===> WriteResult\n"; printWriteResult($result); echo "\n===> Collection\n"; $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query(array())); var_dump(iterator_to_array($cursor)); ?> ===DONE=== --EXPECTF-- ===> WriteResult server: %s:%d insertedCount: 0 matchedCount: 0 modifiedCount: 0 upsertedCount: 1 deletedCount: 0 upsertedId[0]: int(1) ===> Collection array(1) { [0]=> object(stdClass)#%d (2) { ["_id"]=> int(1) ["x"]=> int(1) } } ===DONE=== mongodb-1.1.5/tests/manager/manager-executeBulkWrite-010.phpt0000664000175000017500000000176412673034026023670 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::executeBulkWrite() update multiple documents with upsert --SKIPIF-- --FILE-- update( array('_id' => 1), array('$set' => array('x' => 1)), array('multi' => true, 'upsert' => true) ); $result = $manager->executeBulkWrite(NS, $bulk); echo "\n===> WriteResult\n"; printWriteResult($result); echo "\n===> Collection\n"; $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query(array())); var_dump(iterator_to_array($cursor)); ?> ===DONE=== --EXPECTF-- ===> WriteResult server: %s:%d insertedCount: 0 matchedCount: 0 modifiedCount: 0 upsertedCount: 1 deletedCount: 0 upsertedId[0]: int(1) ===> Collection array(1) { [0]=> object(stdClass)#%d (2) { ["_id"]=> int(1) ["x"]=> int(1) } } ===DONE=== mongodb-1.1.5/tests/manager/manager-executeBulkWrite-011.phpt0000664000175000017500000000422512673034026023664 0ustar jmikolajmikola--TEST-- MongoDB\Driver\BulkWrite: bypassDocumentValidation option --SKIPIF-- --FILE-- COLLECTION_NAME, 'validator' => ['x' => ['$type' => 'number']], ]); $manager->executeCommand(DATABASE_NAME, $command); $bulk = new MongoDB\Driver\BulkWrite(); $bulk->insert(['_id' => 1, 'x' => 1]); $bulk->insert(['_id' => 2, 'x' => 2]); $manager->executeBulkWrite(NS, $bulk); $bulk = new MongoDB\Driver\BulkWrite(['bypassDocumentValidation' => true]); $bulk->update(['_id' => 2], ['$set' => ['x' => 'two']]); $manager->executeBulkWrite(NS, $bulk); $bulk = new MongoDB\Driver\BulkWrite(['bypassDocumentValidation' => true]); $bulk->insert(['_id' => 3, 'x' => 'three']); $manager->executeBulkWrite(NS, $bulk); $bulk = new MongoDB\Driver\BulkWrite(); $bulk->insert(['_id' => 4, 'x' => 'four']); echo throws(function() use($manager, $bulk) { $manager->executeBulkWrite(NS, $bulk); }, "MongoDB\Driver\Exception\BulkWriteException"), "\n"; $bulk = new MongoDB\Driver\BulkWrite(); $bulk->update(['_id' => 1], ['$set' => ['x' => 'one']]); echo throws(function() use($manager, $bulk) { $manager->executeBulkWrite(NS, $bulk); }, "MongoDB\Driver\Exception\BulkWriteException"), "\n"; $bulk = new MongoDB\Driver\BulkWrite(); $bulk->update(['_id' => 2], ['$set' => ['x' => 2]]); $manager->executeBulkWrite(NS, $bulk); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query([])); var_dump(iterator_to_array($cursor)); ?> ===DONE=== --EXPECTF-- OK: Got MongoDB\Driver\Exception\BulkWriteException BulkWrite error :: Document failed validation OK: Got MongoDB\Driver\Exception\BulkWriteException BulkWrite error :: Document failed validation array(3) { [0]=> object(stdClass)#%d (2) { ["_id"]=> int(1) ["x"]=> int(1) } [1]=> object(stdClass)#%d (2) { ["_id"]=> int(2) ["x"]=> int(2) } [2]=> object(stdClass)#%d (2) { ["_id"]=> int(3) ["x"]=> string(5) "three" } } ===DONE=== mongodb-1.1.5/tests/manager/manager-executeBulkWrite_error-001.phpt0000664000175000017500000000274412673034026025100 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::executeBulkWrite() with duplicate key errors (ordered) --SKIPIF-- --FILE-- true]); $bulk->insert(array('_id' => 1)); $bulk->insert(array('_id' => 1)); $bulk->insert(array('_id' => 2)); $bulk->insert(array('_id' => 2)); try { $result = $manager->executeBulkWrite(NS, $bulk); echo "FAILED\n"; } catch (MongoDB\Driver\Exception\BulkWriteException $e) { printf("BulkWriteException: %s\n", $e->getMessage()); echo "\n===> WriteResult\n"; printWriteResult($e->getWriteResult()); } echo "\n===> Collection\n"; $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query(array())); var_dump(iterator_to_array($cursor)); ?> ===DONE=== --EXPECTF-- BulkWriteException: BulkWrite error :: E11000 duplicate key error %s: phongo.manager_manager_executeBulkWrite_error_001%sdup key: { : 1 } ===> WriteResult server: %s:%d insertedCount: 1 matchedCount: 0 modifiedCount: 0 upsertedCount: 0 deletedCount: 0 object(MongoDB\Driver\WriteError)#%d (%d) { ["message"]=> string(%d) "%s" ["code"]=> int(11000) ["index"]=> int(1) ["info"]=> NULL } writeError[1].message: %s writeError[1].code: 11000 ===> Collection array(1) { [0]=> object(stdClass)#%d (1) { ["_id"]=> int(1) } } ===DONE=== mongodb-1.1.5/tests/manager/manager-executeBulkWrite_error-002.phpt0000664000175000017500000000352712673034026025101 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::executeBulkWrite() with duplicate key errors (unordered) --SKIPIF-- --FILE-- false]); $bulk->insert(array('_id' => 1)); $bulk->insert(array('_id' => 1)); $bulk->insert(array('_id' => 2)); $bulk->insert(array('_id' => 2)); try { $result = $manager->executeBulkWrite(NS, $bulk); echo "FAILED\n"; } catch (MongoDB\Driver\Exception\BulkWriteException $e) { printf("BulkWriteException: %s\n", $e->getMessage()); echo "\n===> WriteResult\n"; printWriteResult($e->getWriteResult()); } echo "\n===> Collection\n"; $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query(array())); var_dump(iterator_to_array($cursor)); ?> ===DONE=== --EXPECTF-- BulkWriteException: BulkWrite error :: E11000 duplicate key error %s: phongo.manager_manager_executeBulkWrite_error_002%sdup key: { : 1 } :: E11000 duplicate key error %s: phongo.manager_manager_executeBulkWrite_error_002%sdup key: { : 2 } ===> WriteResult server: %s:%d insertedCount: 2 matchedCount: 0 modifiedCount: 0 upsertedCount: 0 deletedCount: 0 object(MongoDB\Driver\WriteError)#%d (%d) { ["message"]=> string(%d) "%s" ["code"]=> int(11000) ["index"]=> int(1) ["info"]=> NULL } writeError[1].message: %s writeError[1].code: 11000 object(MongoDB\Driver\WriteError)#%d (%d) { ["message"]=> string(%d) "%s" ["code"]=> int(11000) ["index"]=> int(3) ["info"]=> NULL } writeError[3].message: %s writeError[3].code: 11000 ===> Collection array(2) { [0]=> object(stdClass)#%d (1) { ["_id"]=> int(1) } [1]=> object(stdClass)#%d (1) { ["_id"]=> int(2) } } ===DONE=== mongodb-1.1.5/tests/manager/manager-executeBulkWrite_error-003.phpt0000664000175000017500000000264412673034026025101 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::executeBulkWrite() write concern error --SKIPIF-- --FILE-- insert(array('_id' => 1, 'x' => 1)); try { $manager->executeBulkWrite(NS, $bulk, new MongoDB\Driver\WriteConcern(30)); } catch (MongoDB\Driver\Exception\BulkWriteException $e) { printf("BulkWriteException: %s\n", $e->getMessage()); echo "\n===> WriteResult\n"; printWriteResult($e->getWriteResult()); } echo "\n===> Collection\n"; $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query(array())); var_dump(iterator_to_array($cursor)); ?> ===DONE=== --EXPECTF-- BulkWriteException: BulkWrite error :: Not enough data-bearing nodes ===> WriteResult server: %s:%d insertedCount: 1 matchedCount: 0 modifiedCount: 0 upsertedCount: 0 deletedCount: 0 object(MongoDB\Driver\WriteConcernError)#%d (%d) { ["message"]=> string(29) "Not enough data-bearing nodes" ["code"]=> int(100) ["info"]=> NULL } writeConcernError.message: Not enough data-bearing nodes writeConcernError.code: 100 writeConcernError.info: NULL ===> Collection array(1) { [0]=> object(stdClass)#%d (%d) { ["_id"]=> int(1) ["x"]=> int(1) } } ===DONE=== mongodb-1.1.5/tests/manager/manager-executeBulkWrite_error-004.phpt0000664000175000017500000000275412673034026025104 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::executeBulkWrite() delete write error --SKIPIF-- --FILE-- insert(array('_id' => 1, 'x' => 1)); $manager->executeBulkWrite(NS, $bulk); $bulk = new MongoDB\Driver\BulkWrite(); $bulk->delete(['$foo' => 1], ['limit' => 1]); try { $manager->executeBulkWrite(NS, $bulk); } catch (MongoDB\Driver\Exception\BulkWriteException $e) { printf("BulkWriteException: %s\n", $e->getMessage()); echo "\n===> WriteResult\n"; printWriteResult($e->getWriteResult()); } echo "\n===> Collection\n"; $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query(array())); var_dump(iterator_to_array($cursor)); ?> ===DONE=== --EXPECTF-- BulkWriteException: BulkWrite error :: unknown top level operator: $foo ===> WriteResult server: %s:%d insertedCount: 0 matchedCount: 0 modifiedCount: 0 upsertedCount: 0 deletedCount: 0 object(MongoDB\Driver\WriteError)#%d (%d) { ["message"]=> string(32) "unknown top level operator: $foo" ["code"]=> int(2) ["index"]=> int(0) ["info"]=> NULL } writeError[0].message: unknown top level operator: $foo writeError[0].code: 2 ===> Collection array(1) { [0]=> object(stdClass)#%d (%d) { ["_id"]=> int(1) ["x"]=> int(1) } } ===DONE=== mongodb-1.1.5/tests/manager/manager-executeBulkWrite_error-005.phpt0000664000175000017500000000215612673034026025101 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::executeBulkWrite() insert write error --SKIPIF-- --FILE-- insert(['$foo' => 1]); try { $manager->executeBulkWrite(NS, $bulk); } catch (MongoDB\Driver\Exception\BulkWriteException $e) { printf("BulkWriteException: %s\n", $e->getMessage()); echo "\n===> WriteResult\n"; printWriteResult($e->getWriteResult()); } ?> ===DONE=== --EXPECTF-- BulkWriteException: BulkWrite error :: Document can't have $ prefixed field names: $foo ===> WriteResult server: %s:%d insertedCount: 0 matchedCount: 0 modifiedCount: 0 upsertedCount: 0 deletedCount: 0 object(MongoDB\Driver\WriteError)#%d (%d) { ["message"]=> string(48) "Document can't have $ prefixed field names: $foo" ["code"]=> int(2) ["index"]=> int(0) ["info"]=> NULL } writeError[0].message: Document can't have $ prefixed field names: $foo writeError[0].code: 2 ===DONE=== mongodb-1.1.5/tests/manager/manager-executeBulkWrite_error-006.phpt0000664000175000017500000000223412673034026025077 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::executeBulkWrite() update write error --SKIPIF-- --FILE-- insert(array('x' => 1)); $manager->executeBulkWrite(NS, $bulk); $bulk = new MongoDB\Driver\BulkWrite(); $bulk->update(['x' => 1], ['$foo' => 1]); try { $manager->executeBulkWrite(NS, $bulk); } catch (MongoDB\Driver\Exception\BulkWriteException $e) { printf("BulkWriteException: %s\n", $e->getMessage()); echo "\n===> WriteResult\n"; printWriteResult($e->getWriteResult()); } ?> ===DONE=== --EXPECTF-- BulkWriteException: BulkWrite error :: Unknown modifier: $foo ===> WriteResult server: %s:%d insertedCount: 0 matchedCount: 0 modifiedCount: 0 upsertedCount: 0 deletedCount: 0 object(MongoDB\Driver\WriteError)#%d (%d) { ["message"]=> string(22) "Unknown modifier: $foo" ["code"]=> int(9) ["index"]=> int(0) ["info"]=> NULL } writeError[0].message: Unknown modifier: $foo writeError[0].code: 9 ===DONE=== mongodb-1.1.5/tests/manager/manager-executeBulkWrite_error-007.phpt0000664000175000017500000000223212673034026025076 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::executeBulkWrite() should not issue warning before exception --SKIPIF-- --FILE-- insert(['x' => 1]); // Invalid host cannot be resolved $manager = new MongoDB\Driver\Manager('mongodb://invalid.host:27017', ['serverSelectionTimeoutMS' => 1]); echo throws(function() use ($manager, $bulk) { $manager->executeBulkWrite(NS, $bulk); }, 'MongoDB\Driver\Exception\ConnectionTimeoutException'), "\n"; // Valid host refuses connection $manager = new MongoDB\Driver\Manager('mongodb://localhost:54321', ['serverSelectionTimeoutMS' => 1]); echo throws(function() use ($manager, $bulk) { $manager->executeBulkWrite(NS, $bulk); }, 'MongoDB\Driver\Exception\ConnectionTimeoutException'), "\n"; ?> ===DONE=== --EXPECTF-- OK: Got MongoDB\Driver\Exception\ConnectionTimeoutException No suitable servers found (`serverselectiontryonce` set): %s OK: Got MongoDB\Driver\Exception\ConnectionTimeoutException No suitable servers found (`serverselectiontryonce` set): %s ===DONE=== mongodb-1.1.5/tests/manager/manager-executeCommand-001.phpt0000664000175000017500000000346712673034026023340 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::executeCommand() --SKIPIF-- --FILE-- 1)); $result = $manager->executeCommand(DATABASE_NAME, $command); var_dump($command); var_dump($result instanceof MongoDB\Driver\Cursor); var_dump($result); echo "\nDumping response document:\n"; var_dump(current($result->toArray())); $server = $result->getServer(); var_dump($server instanceof MongoDB\Driver\Server); var_dump($server->getHost()); var_dump($server->getPort()); ?> ===DONE=== --EXPECTF-- object(MongoDB\Driver\Command)#%d (1) { ["command"]=> object(stdClass)#%d (1) { ["ping"]=> int(1) } } bool(true) object(MongoDB\Driver\Cursor)#%d (%d) { ["cursor"]=> array(%d) { ["stamp"]=> int(0) ["is_command"]=> bool(true) ["sent"]=> bool(true) ["done"]=> bool(false) ["end_of_event"]=> bool(false) ["in_exhaust"]=> bool(false) ["has_fields"]=> bool(false) ["query"]=> object(stdClass)#%d (1) { ["ping"]=> int(1) } ["fields"]=> object(stdClass)#%d (0) { } ["read_preference"]=> array(2) { ["mode"]=> int(1) ["tags"]=> array(0) { } } ["flags"]=> int(0) ["skip"]=> int(0) ["limit"]=> int(1) ["count"]=> int(1) ["batch_size"]=> int(0) ["ns"]=> string(11) "phongo.$cmd" ["current_doc"]=> object(stdClass)#%d (1) { ["ok"]=> float(1) } } ["server_id"]=> int(1) } Dumping response document: object(stdClass)#%d (1) { ["ok"]=> float(1) } bool(true) string(%d) "%s" int(%d) ===DONE=== mongodb-1.1.5/tests/manager/manager-executeCommand_error-001.phpt0000664000175000017500000000225312673034026024541 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::executeCommand() should not issue warning before exception --SKIPIF-- --FILE-- 1]); // Invalid host cannot be resolved $manager = new MongoDB\Driver\Manager('mongodb://invalid.host:27017', ['serverSelectionTimeoutMS' => 1]); echo throws(function() use ($manager, $command) { $manager->executeCommand(DATABASE_NAME, $command); }, 'MongoDB\Driver\Exception\ConnectionTimeoutException'), "\n"; // Valid host refuses connection $manager = new MongoDB\Driver\Manager('mongodb://localhost:54321', ['serverSelectionTimeoutMS' => 1]); echo throws(function() use ($manager, $command) { $manager->executeCommand(DATABASE_NAME, $command); }, 'MongoDB\Driver\Exception\ConnectionTimeoutException'), "\n"; ?> ===DONE=== --EXPECTF-- OK: Got MongoDB\Driver\Exception\ConnectionTimeoutException No suitable servers found (`serverselectiontryonce` set): %s OK: Got MongoDB\Driver\Exception\ConnectionTimeoutException No suitable servers found (`serverselectiontryonce` set): %s ===DONE=== mongodb-1.1.5/tests/manager/manager-executeQuery-001.phpt0000664000175000017500000000416612673034026023064 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::executeQuery() one document (OP_QUERY) --SKIPIF-- --FILE-- insert(array('_id' => 1, 'x' => 2, 'y' => 3)); $bulk->insert(array('_id' => 2, 'x' => 3, 'y' => 4)); $bulk->insert(array('_id' => 3, 'x' => 4, 'y' => 5)); $manager->executeBulkWrite(NS, $bulk); $query = new MongoDB\Driver\Query(array('x' => 3), array('projection' => array('y' => 1))); $qr = $manager->executeQuery(NS, $query); var_dump($qr instanceof MongoDB\Driver\Cursor); var_dump($qr); $server = $qr->getServer(); var_dump($server instanceof MongoDB\Driver\Server); var_dump($server->getHost()); var_dump($server->getPort()); var_dump(iterator_to_array($qr)); ?> ===DONE=== --EXPECTF-- bool(true) object(MongoDB\Driver\Cursor)#%d (%d) { ["cursor"]=> array(%d) { ["stamp"]=> int(0) ["is_command"]=> bool(false) ["sent"]=> bool(true) ["done"]=> bool(false) ["end_of_event"]=> bool(false) ["in_exhaust"]=> bool(false) ["has_fields"]=> bool(true) ["query"]=> object(stdClass)#%d (%d) { ["$query"]=> object(stdClass)#%d (%d) { ["x"]=> int(3) } } ["fields"]=> object(stdClass)#%d (%d) { ["y"]=> int(1) } ["read_preference"]=> array(2) { ["mode"]=> int(1) ["tags"]=> array(0) { } } ["flags"]=> int(0) ["skip"]=> int(0) ["limit"]=> int(0) ["count"]=> int(1) ["batch_size"]=> int(0) ["ns"]=> string(39) "phongo.manager_manager_executeQuery_001" ["current_doc"]=> object(stdClass)#%d (2) { ["_id"]=> int(2) ["y"]=> int(4) } } ["server_id"]=> int(1) } bool(true) string(%d) "%s" int(%d) array(1) { [0]=> object(stdClass)#%d (2) { ["_id"]=> int(2) ["y"]=> int(4) } } ===DONE=== mongodb-1.1.5/tests/manager/manager-executeQuery-002.phpt0000664000175000017500000000433012673034026023056 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::executeQuery() one document (find command) --SKIPIF-- --FILE-- insert(array('_id' => 1, 'x' => 2, 'y' => 3)); $bulk->insert(array('_id' => 2, 'x' => 3, 'y' => 4)); $bulk->insert(array('_id' => 3, 'x' => 4, 'y' => 5)); $manager->executeBulkWrite(NS, $bulk); $query = new MongoDB\Driver\Query(array('x' => 3), array('projection' => array('y' => 1))); $qr = $manager->executeQuery(NS, $query); var_dump($qr instanceof MongoDB\Driver\Cursor); var_dump($qr); $server = $qr->getServer(); var_dump($server instanceof MongoDB\Driver\Server); var_dump($server->getHost()); var_dump($server->getPort()); var_dump(iterator_to_array($qr)); ?> ===DONE=== --EXPECTF-- bool(true) object(MongoDB\Driver\Cursor)#%d (%d) { ["cursor"]=> array(%d) { ["stamp"]=> int(0) ["is_command"]=> bool(false) ["sent"]=> bool(true) ["done"]=> bool(false) ["end_of_event"]=> bool(false) ["in_exhaust"]=> bool(false) ["has_fields"]=> bool(true) ["query"]=> object(stdClass)#%d (%d) { ["find"]=> string(%d) "%s" ["filter"]=> object(stdClass)#%d (%d) { ["x"]=> int(3) } ["projection"]=> object(stdClass)#%d (%d) { ["y"]=> int(1) } } ["fields"]=> object(stdClass)#%d (%d) { ["y"]=> int(1) } ["read_preference"]=> array(2) { ["mode"]=> int(1) ["tags"]=> array(0) { } } ["flags"]=> int(0) ["skip"]=> int(0) ["limit"]=> int(0) ["count"]=> int(1) ["batch_size"]=> int(0) ["ns"]=> string(39) "phongo.manager_manager_executeQuery_002" ["current_doc"]=> object(stdClass)#%d (2) { ["_id"]=> int(2) ["y"]=> int(4) } } ["server_id"]=> int(1) } bool(true) string(%d) "%s" int(%d) array(1) { [0]=> object(stdClass)#%d (2) { ["_id"]=> int(2) ["y"]=> int(4) } } ===DONE=== mongodb-1.1.5/tests/manager/manager-executeQuery-005.phpt0000664000175000017500000000330112673034026023056 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Server::executeQuery() with filter and projection --SKIPIF-- --FILE-- insert(array('_id' => 1, array('x' => 2, 'y' => 3))); $bulk->insert(array('_id' => 2, array('x' => 3, 'y' => 4))); $bulk->insert(array('_id' => 3, array('x' => 4, 'y' => 5))); $manager->executeBulkWrite(NS, $bulk); $query = new MongoDB\Driver\Query(array()); $qr = $manager->executeQuery(NS, $query); $qr->setTypeMap(array("root"=> "MyArrayObject", "document"=> "MyArrayObject", "array" => "MyArrayObject")); foreach($qr as $obj) { var_dump($obj); } ?> ===DONE=== --EXPECTF-- object(MyArrayObject)#%d (1) { [%s]=> array(2) { ["_id"]=> int(1) [0]=> object(MyArrayObject)#%d (1) { [%s]=> array(2) { ["x"]=> int(2) ["y"]=> int(3) } } } } object(MyArrayObject)#%d (1) { [%s]=> array(2) { ["_id"]=> int(2) [0]=> object(MyArrayObject)#%d (1) { [%s]=> array(2) { ["x"]=> int(3) ["y"]=> int(4) } } } } object(MyArrayObject)#%d (1) { [%s]=> array(2) { ["_id"]=> int(3) [0]=> object(MyArrayObject)#%d (1) { [%s]=> array(2) { ["x"]=> int(4) ["y"]=> int(5) } } } } ===DONE=== mongodb-1.1.5/tests/manager/manager-executeQuery_error-001.phpt0000664000175000017500000000217012673034026024266 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::executeQuery() should not issue warning before exception --SKIPIF-- --FILE-- 1]); echo throws(function() use ($manager, $query) { $manager->executeQuery(NS, $query); }, 'MongoDB\Driver\Exception\ConnectionTimeoutException'), "\n"; // Valid host refuses connection $manager = new MongoDB\Driver\Manager('mongodb://localhost:54321', ['serverSelectionTimeoutMS' => 1]); echo throws(function() use ($manager, $query) { $manager->executeQuery(NS, $query); }, 'MongoDB\Driver\Exception\ConnectionTimeoutException'), "\n"; ?> ===DONE=== --EXPECTF-- OK: Got MongoDB\Driver\Exception\ConnectionTimeoutException No suitable servers found (`serverselectiontryonce` set): %s OK: Got MongoDB\Driver\Exception\ConnectionTimeoutException No suitable servers found (`serverselectiontryonce` set): %s ===DONE=== mongodb-1.1.5/tests/manager/manager-executequery-without-assignment.phpt0000664000175000017500000000154412673034026026472 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager: Executing Query without assignment still executes --SKIPIF-- --FILE-- insert(array('_id' => 1, 'x' => 1)); $bulk->insert(array('_id' => 2, 'x' => 1)); $manager->executeBulkWrite(NS, $bulk); ini_set("mongodb.debug", "stdout"); $manager->executeQuery(NS, new MongoDB\Driver\Query(array("x" => 1))); ini_set("mongodb.debug", "off"); ?> ===DONE=== --EXPECTF-- %a [%s] cursor: TRACE > ENTRY: mongoc_cursor_next():%d %a [%s] cursor: TRACE > EXIT: mongoc_cursor_destroy():%d ===DONE=== mongodb-1.1.5/tests/manager/manager-getreadconcern-001.phpt0000664000175000017500000000310012673034026023342 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::getReadConcern() --SKIPIF-- --FILE-- 'local']], [STANDALONE, ['readconcernlevel' => 'majority']], [STANDALONE, ['readconcernlevel' => 'not-yet-supported']], [STANDALONE . '/?readconcernlevel=local', ['readconcernlevel' => 'majority']], ]; foreach ($tests as $i => $test) { list($uri, $options) = $test; $manager = new MongoDB\Driver\Manager($uri, $options); var_dump($manager->getReadConcern()); // Test for !return_value_used $manager->getReadConcern(); } ?> ===DONE=== --EXPECTF-- object(MongoDB\Driver\ReadConcern)#%d (%d) { ["level"]=> NULL } object(MongoDB\Driver\ReadConcern)#%d (%d) { ["level"]=> string(5) "local" } object(MongoDB\Driver\ReadConcern)#%d (%d) { ["level"]=> string(8) "majority" } object(MongoDB\Driver\ReadConcern)#%d (%d) { ["level"]=> string(17) "not-yet-supported" } object(MongoDB\Driver\ReadConcern)#%d (%d) { ["level"]=> string(5) "local" } object(MongoDB\Driver\ReadConcern)#%d (%d) { ["level"]=> string(8) "majority" } object(MongoDB\Driver\ReadConcern)#%d (%d) { ["level"]=> string(17) "not-yet-supported" } object(MongoDB\Driver\ReadConcern)#%d (%d) { ["level"]=> string(8) "majority" } ===DONE=== mongodb-1.1.5/tests/manager/manager-getreadpreference-001.phpt0000664000175000017500000000430412673034026024040 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::getReadPreference() --SKIPIF-- --FILE-- 'primaryPreferred')), array(STANDALONE . '/?readPreference=secondary', array('readPreference' => 'secondaryPreferred')), array(STANDALONE . '/?readPreference=secondary&readPreferenceTags=dc:ny,use:reports&readPreferenceTags=', array()), array(STANDALONE . '/?readPreference=secondary', array('readPreferenceTags' => array(array('dc' => 'ny', 'use' => 'reports'), array()))), array(STANDALONE . '/?readPreference=secondary&readPreferenceTags=dc:ny,use:reports', array('readPreferenceTags' => array(array('dc' => 'ca')))), ); foreach ($tests as $i => $test) { list($uri, $options) = $test; $manager = new MongoDB\Driver\Manager($uri, $options); var_dump($manager->getReadPreference()); // Test for !return_value_used $manager->getReadPreference(); } ?> ===DONE=== --EXPECTF-- object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> int(1) ["tags"]=> array(0) { } } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> int(2) ["tags"]=> array(0) { } } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> int(5) ["tags"]=> array(0) { } } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> int(6) ["tags"]=> array(0) { } } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> int(2) ["tags"]=> array(2) { [0]=> array(2) { ["dc"]=> string(2) "ny" ["use"]=> string(7) "reports" } [1]=> array(0) { } } } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> int(2) ["tags"]=> array(2) { [0]=> array(2) { ["dc"]=> string(2) "ny" ["use"]=> string(7) "reports" } [1]=> array(0) { } } } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> int(2) ["tags"]=> array(1) { [0]=> array(1) { ["dc"]=> string(2) "ca" } } } ===DONE=== mongodb-1.1.5/tests/manager/manager-getservers-001.phpt0000664000175000017500000000210712673034026022556 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::getServers() (standalone) --SKIPIF-- --FILE-- getServers(); printf("Known servers: %d\n", count($servers)); echo "Pinging\n"; $command = new MongoDB\Driver\Command(array('ping' => 1)); $manager->executeCommand(DATABASE_NAME, $command); $servers = $manager->getServers(); printf("Known servers: %d\n", count($servers)); foreach ($servers as $server) { printf("Found server: %s:%d\n", $server->getHost(), $server->getPort()); assertServerType($server->getType()); } ?> ===DONE=== --EXPECTF-- Known servers: 0 Pinging Known servers: 1 Found server: %s:%d Found standalone server type: 1 ===DONE=== mongodb-1.1.5/tests/manager/manager-getservers-002.phpt0000664000175000017500000000261712673034026022565 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::getServers() (replica set) --SKIPIF-- --FILE-- getServers(); printf("Known servers: %d\n", count($servers)); echo "Pinging\n"; $command = new MongoDB\Driver\Command(array('ping' => 1)); $manager->executeCommand(DATABASE_NAME, $command); $servers = $manager->getServers(); printf("Known servers: %d\n", count($servers)); foreach ($servers as $server) { printf("Found server: %s:%d\n", $server->getHost(), $server->getPort()); assertServerType($server->getType()); } ?> ===DONE=== --EXPECTF-- Known servers: 0 Pinging Known servers: 3 Found server: %s:%d Found replica set server type: %r(4|5|6)%r Found server: %s:%d Found replica set server type: %r(4|5|6)%r Found server: %s:%d Found replica set server type: %r(4|5|6)%r ===DONE=== mongodb-1.1.5/tests/manager/manager-getwriteconcern-001.phpt0000664000175000017500000000557712673034026023605 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::getWriteConcern() --SKIPIF-- --FILE-- 1, 'journal' => true)), array(STANDALONE, array('w' => 'majority', 'journal' => true)), array(STANDALONE . '/?w=majority&journal=true', array('w' => 1, 'journal' => false)), // wtimeoutms does not get applied unless w > 1, w = majority, or tag sets are used array(STANDALONE . '/?wtimeoutms=1000', array()), array(STANDALONE, array('wtimeoutms' => 1000)), array(STANDALONE . '/?w=2', array('wtimeoutms' => 1000)), array(STANDALONE . '/?w=majority', array('wtimeoutms' => 1000)), array(STANDALONE . '/?w=customTagSet', array('wtimeoutms' => 1000)), ); foreach ($tests as $i => $test) { list($uri, $options) = $test; $manager = new MongoDB\Driver\Manager($uri, $options); var_dump($manager->getWriteConcern()); // Test for !return_value_used $manager->getWriteConcern(); } ?> ===DONE=== --EXPECTF-- object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> NULL ["wmajority"]=> bool(false) ["wtimeout"]=> int(0) ["journal"]=> NULL } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> int(1) ["wmajority"]=> bool(false) ["wtimeout"]=> int(0) ["journal"]=> NULL } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> string(8) "majority" ["wmajority"]=> bool(true) ["wtimeout"]=> int(0) ["journal"]=> NULL } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> int(1) ["wmajority"]=> bool(false) ["wtimeout"]=> int(0) ["journal"]=> bool(true) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> string(8) "majority" ["wmajority"]=> bool(true) ["wtimeout"]=> int(0) ["journal"]=> bool(true) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> int(1) ["wmajority"]=> bool(false) ["wtimeout"]=> int(0) ["journal"]=> bool(false) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> NULL ["wmajority"]=> bool(false) ["wtimeout"]=> int(0) ["journal"]=> NULL } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> NULL ["wmajority"]=> bool(false) ["wtimeout"]=> int(0) ["journal"]=> NULL } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> int(2) ["wmajority"]=> bool(false) ["wtimeout"]=> int(1000) ["journal"]=> NULL } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> string(8) "majority" ["wmajority"]=> bool(true) ["wtimeout"]=> int(1000) ["journal"]=> NULL } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> string(12) "customTagSet" ["wmajority"]=> bool(false) ["wtimeout"]=> int(1000) ["journal"]=> NULL } ===DONE=== mongodb-1.1.5/tests/manager/manager-invalidnamespace.phpt0000664000175000017500000000161112673034026023371 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager: Invalid namespace --SKIPIF-- --FILE-- insert(array("my" => "value")); echo throws(function() use($manager, $bulk) { $manager->executeBulkWrite("database", $bulk); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; echo throws(function() use($manager) { $manager->executeQuery("database", new MongoDB\Driver\Query(array("document "=> 1))); }, "MongoDB\Driver\Exception\InvalidArgumentException"), "\n"; ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Invalid namespace provided: database OK: Got MongoDB\Driver\Exception\InvalidArgumentException Invalid namespace provided: database ===DONE=== mongodb-1.1.5/tests/manager/manager-selectserver-001.phpt0000664000175000017500000000400712673034026023074 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::selectServer() select a server from SDAM based on ReadPreference --SKIPIF-- --FILE-- selectServer($rp); $rp2 = new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_PRIMARY); $server2 = $manager->selectServer($rp2); // load fixtures for test $bulk = new \MongoDB\Driver\BulkWrite(); $bulk->insert(array('_id' => 1, 'x' => 2, 'y' => 3)); $bulk->insert(array('_id' => 2, 'x' => 3, 'y' => 4)); $bulk->insert(array('_id' => 3, 'x' => 4, 'y' => 5)); $server->executeBulkWrite(NS, $bulk); $query = new MongoDB\Driver\Query(array('x' => 3), array('projection' => array('y' => 1))); $cursor = $server->executeQuery(NS, $query); var_dump($cursor instanceof MongoDB\Driver\Cursor); var_dump($server == $cursor->getServer()); var_dump(iterator_to_array($cursor)); $query = new MongoDB\Driver\Query(array('x' => 3), array('projection' => array('y' => 1))); $cursor = $server2->executeQuery(NS, $query); var_dump($cursor instanceof MongoDB\Driver\Cursor); var_dump($server2 == $cursor->getServer()); var_dump(iterator_to_array($cursor)); $bulk = new \MongoDB\Driver\BulkWrite(); $bulk->insert(array('_id' => 1, 'x' => 2, 'y' => 3)); $bulk->insert(array('_id' => 2, 'x' => 3, 'y' => 4)); $bulk->insert(array('_id' => 3, 'x' => 4, 'y' => 5)); throws(function() use($server2, $bulk) { $server2->executeBulkWrite(NS, $bulk); }, "MongoDB\Driver\Exception\BulkWriteException"); ?> ===DONE=== --EXPECTF-- bool(true) bool(true) array(1) { [0]=> object(stdClass)#%d (2) { ["_id"]=> int(2) ["y"]=> int(4) } } bool(true) bool(true) array(1) { [0]=> object(stdClass)#%d (2) { ["_id"]=> int(2) ["y"]=> int(4) } } OK: Got MongoDB\Driver\Exception\BulkWriteException ===DONE=== mongodb-1.1.5/tests/manager/manager-selectserver_error-001.phpt0000664000175000017500000000222112673034026024301 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::selectServer() should not issue warning before exception --SKIPIF-- --FILE-- 1]); echo throws(function() use ($manager, $rp) { $manager->selectServer($rp); }, 'MongoDB\Driver\Exception\ConnectionTimeoutException'), "\n"; // Valid host refuses connection $manager = new MongoDB\Driver\Manager('mongodb://localhost:54321', ['serverSelectionTimeoutMS' => 1]); echo throws(function() use ($manager, $rp) { $manager->selectServer($rp); }, 'MongoDB\Driver\Exception\ConnectionTimeoutException'), "\n"; ?> ===DONE=== --EXPECTF-- OK: Got MongoDB\Driver\Exception\ConnectionTimeoutException No suitable servers found (`serverselectiontryonce` set): %s OK: Got MongoDB\Driver\Exception\ConnectionTimeoutException No suitable servers found (`serverselectiontryonce` set): %s ===DONE=== mongodb-1.1.5/tests/manager/manager-set-uri-options-001.phpt0000664000175000017500000000237612673034026023456 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager: Logging into MongoDB using credentials from $options --SKIPIF-- --FILE-- $url["user"], "password" => $url["pass"], ) + $args; $manager = new MongoDB\Driver\Manager($dsn, $options); $bulk = new MongoDB\Driver\BulkWrite; $bulk->insert(array("my" => "value")); $inserted = $manager->executeBulkWrite(NS, $bulk)->getInsertedCount(); printf("Inserted: %d\n", $inserted); $options["username"] = "not-found-user"; $manager = new MongoDB\Driver\Manager($dsn, $options); $bulk = new MongoDB\Driver\BulkWrite; $bulk->insert(array("my" => "value")); throws(function() use ($manager, $bulk) { $inserted = $manager->executeBulkWrite(NS, $bulk)->getInsertedCount(); printf("Incorrectly inserted: %d\n", $inserted); }, "MongoDB\Driver\Exception\AuthenticationException"); ?> ===DONE=== --EXPECTF-- Inserted: 1 OK: Got MongoDB\Driver\Exception\AuthenticationException ===DONE=== mongodb-1.1.5/tests/manager/manager-set-uri-options-002.phpt0000664000175000017500000000244112673034026023450 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager: Logging into MongoDB using credentials from $options --SKIPIF-- --FILE-- array( "verify_peer" => false, "verify_peer_name" => false, "allow_self_signed" => true, ), ); $context = stream_context_create($opts); $options = array( "ssl" => false, "serverselectiontimeoutms" => 100, ); /* The server requires SSL */ $manager = new MongoDB\Driver\Manager(STANDALONE_SSL, $options, array("context" => $context)); $bulk = new MongoDB\Driver\BulkWrite; $bulk->insert(array("my" => "value")); throws(function() use ($manager, $bulk) { $inserted = $manager->executeBulkWrite(NS, $bulk)->getInsertedCount(); printf("Inserted incorrectly: %d\n", $inserted); }, "Exception"); $options = array( "ssl" => true, ); $manager = new MongoDB\Driver\Manager(STANDALONE_SSL, $options, array("context" => $context)); $bulk = new MongoDB\Driver\BulkWrite; $bulk->insert(array("my" => "value")); $inserted = $manager->executeBulkWrite(NS, $bulk)->getInsertedCount(); printf("Inserted: %d\n", $inserted); ?> ===DONE=== --EXPECTF-- OK: Got Exception Inserted: 1 ===DONE=== mongodb-1.1.5/tests/manager/manager-var-dump-001.phpt0000664000175000017500000000406512673034026022125 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager: Constructing invalid manager --SKIPIF-- --FILE-- insert(array("my" => "value")); $retval = $manager->executeBulkWrite(NS, $bulk); var_dump($manager); ?> ===DONE=== --EXPECTF-- object(MongoDB\Driver\Manager)#%d (%d) { ["uri"]=> string(%d) "mongodb://%s" ["cluster"]=> array(1) { [0]=> array(11) { ["host"]=> string(%d) "%s" ["port"]=> int(%d) ["type"]=> int(0) ["is_primary"]=> bool(false) ["is_secondary"]=> bool(false) ["is_arbiter"]=> bool(false) ["is_hidden"]=> bool(false) ["is_passive"]=> bool(false) ["tags"]=> array(0) { } ["last_is_master"]=> array(0) { } ["round_trip_time"]=> int(-1) } } } object(MongoDB\Driver\Manager)#%d (%d) { ["uri"]=> string(%d) "mongodb://%s" ["cluster"]=> array(1) { [0]=> array(10) { ["host"]=> string(%d) "%s" ["port"]=> int(%d) ["type"]=> int(1) ["is_primary"]=> bool(false) ["is_secondary"]=> bool(false) ["is_arbiter"]=> bool(false) ["is_hidden"]=> bool(false) ["is_passive"]=> bool(false) ["last_is_master"]=> array(8) { ["ismaster"]=> bool(true) ["maxBsonObjectSize"]=> int(16777216) ["maxMessageSizeBytes"]=> int(48000000) ["maxWriteBatchSize"]=> int(1000) ["localTime"]=> object(%s\UTCDateTime)#%d (%d) { ["milliseconds"]=> %r(int\(\d+\)|string\(\d+\) "\d+")%r } ["maxWireVersion"]=> int(%d) ["minWireVersion"]=> int(0) ["ok"]=> float(1) } ["round_trip_time"]=> int(%d) } } } ===DONE=== mongodb-1.1.5/tests/manager/manager-wakeup.phpt0000664000175000017500000000110512673034026021360 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager: Manager cannot be woken up --SKIPIF-- --FILE-- __wakeUp(); }, "MongoDB\Driver\Exception\RuntimeException"); $manager->__wakeUp(1, 2); ?> ===DONE=== --EXPECTF-- OK: Got MongoDB\Driver\Exception\RuntimeException Warning: MongoDB\Driver\Manager::__wakeUp() expects exactly 0 parameters, 2 given in %s on line %d ===DONE=== mongodb-1.1.5/tests/manager/manager_error-001.phpt0000664000175000017500000000056012673034026021601 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Query cannot be extended --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- Fatal error: Class MyQuery may not inherit from final class (MongoDB\Driver\Query) in %s on line %d mongodb-1.1.5/tests/readPreference/bug0146-001.phpt0000664000175000017500000001201412673034026021343 0ustar jmikolajmikola--TEST-- PHPC-146: ReadPreference primaryPreferred and secondary swapped (OP_QUERY) --SKIPIF-- --FILE-- insert(array('my' => 'document')); $manager->executeBulkWrite(NS, $bulk); $rps = array( MongoDB\Driver\ReadPreference::RP_PRIMARY, MongoDB\Driver\ReadPreference::RP_PRIMARY_PREFERRED, MongoDB\Driver\ReadPreference::RP_SECONDARY, MongoDB\Driver\ReadPreference::RP_SECONDARY_PREFERRED, MongoDB\Driver\ReadPreference::RP_NEAREST, ); foreach($rps as $r) { $rp = new MongoDB\Driver\ReadPreference($r); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query(array("my" => "query")), $rp); var_dump($cursor); } ?> ===DONE=== --EXPECTF-- object(MongoDB\Driver\Cursor)#%d (%d) { ["cursor"]=> array(%d) { ["stamp"]=> int(0) ["is_command"]=> bool(false) ["sent"]=> bool(true) ["done"]=> bool(true) ["end_of_event"]=> bool(true) ["in_exhaust"]=> bool(false) ["has_fields"]=> bool(false) ["query"]=> object(stdClass)#%d (%d) { ["$query"]=> object(stdClass)#%d (%d) { ["my"]=> string(5) "query" } } ["fields"]=> object(stdClass)#%d (0) { } ["read_preference"]=> array(2) { ["mode"]=> int(1) ["tags"]=> array(0) { } } ["flags"]=> int(0) ["skip"]=> int(0) ["limit"]=> int(0) ["count"]=> int(1) ["batch_size"]=> int(0) ["ns"]=> string(%d) "%s" } ["server_id"]=> int(1) } object(MongoDB\Driver\Cursor)#%d (%d) { ["cursor"]=> array(%d) { ["stamp"]=> int(0) ["is_command"]=> bool(false) ["sent"]=> bool(true) ["done"]=> bool(true) ["end_of_event"]=> bool(true) ["in_exhaust"]=> bool(false) ["has_fields"]=> bool(false) ["query"]=> object(stdClass)#%d (%d) { ["$query"]=> object(stdClass)#%d (%d) { ["my"]=> string(5) "query" } } ["fields"]=> object(stdClass)#%d (0) { } ["read_preference"]=> array(2) { ["mode"]=> int(5) ["tags"]=> array(0) { } } ["flags"]=> int(0) ["skip"]=> int(0) ["limit"]=> int(0) ["count"]=> int(1) ["batch_size"]=> int(0) ["ns"]=> string(%d) "%s" } ["server_id"]=> int(1) } object(MongoDB\Driver\Cursor)#%d (%d) { ["cursor"]=> array(%d) { ["stamp"]=> int(0) ["is_command"]=> bool(false) ["sent"]=> bool(true) ["done"]=> bool(true) ["end_of_event"]=> bool(true) ["in_exhaust"]=> bool(false) ["has_fields"]=> bool(false) ["query"]=> object(stdClass)#%d (%d) { ["$query"]=> object(stdClass)#%d (%d) { ["my"]=> string(5) "query" } } ["fields"]=> object(stdClass)#%d (0) { } ["read_preference"]=> array(2) { ["mode"]=> int(2) ["tags"]=> array(0) { } } ["flags"]=> int(0) ["skip"]=> int(0) ["limit"]=> int(0) ["count"]=> int(1) ["batch_size"]=> int(0) ["ns"]=> string(%d) "%s" } ["server_id"]=> int(1) } object(MongoDB\Driver\Cursor)#%d (%d) { ["cursor"]=> array(%d) { ["stamp"]=> int(0) ["is_command"]=> bool(false) ["sent"]=> bool(true) ["done"]=> bool(true) ["end_of_event"]=> bool(true) ["in_exhaust"]=> bool(false) ["has_fields"]=> bool(false) ["query"]=> object(stdClass)#%d (%d) { ["$query"]=> object(stdClass)#%d (%d) { ["my"]=> string(5) "query" } } ["fields"]=> object(stdClass)#%d (0) { } ["read_preference"]=> array(2) { ["mode"]=> int(6) ["tags"]=> array(0) { } } ["flags"]=> int(0) ["skip"]=> int(0) ["limit"]=> int(0) ["count"]=> int(1) ["batch_size"]=> int(0) ["ns"]=> string(%d) "%s" } ["server_id"]=> int(1) } object(MongoDB\Driver\Cursor)#%d (%d) { ["cursor"]=> array(%d) { ["stamp"]=> int(0) ["is_command"]=> bool(false) ["sent"]=> bool(true) ["done"]=> bool(true) ["end_of_event"]=> bool(true) ["in_exhaust"]=> bool(false) ["has_fields"]=> bool(false) ["query"]=> object(stdClass)#%d (%d) { ["$query"]=> object(stdClass)#%d (%d) { ["my"]=> string(5) "query" } } ["fields"]=> object(stdClass)#%d (0) { } ["read_preference"]=> array(2) { ["mode"]=> int(10) ["tags"]=> array(0) { } } ["flags"]=> int(0) ["skip"]=> int(0) ["limit"]=> int(0) ["count"]=> int(1) ["batch_size"]=> int(0) ["ns"]=> string(%d) "%s" } ["server_id"]=> int(1) } ===DONE=== mongodb-1.1.5/tests/readPreference/bug0146-002.phpt0000664000175000017500000001230212673034026021344 0ustar jmikolajmikola--TEST-- PHPC-146: ReadPreference primaryPreferred and secondary swapped (find command) --SKIPIF-- --FILE-- insert(array('my' => 'document')); $manager->executeBulkWrite(NS, $bulk); $rps = array( MongoDB\Driver\ReadPreference::RP_PRIMARY, MongoDB\Driver\ReadPreference::RP_PRIMARY_PREFERRED, MongoDB\Driver\ReadPreference::RP_SECONDARY, MongoDB\Driver\ReadPreference::RP_SECONDARY_PREFERRED, MongoDB\Driver\ReadPreference::RP_NEAREST, ); foreach($rps as $r) { $rp = new MongoDB\Driver\ReadPreference($r); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query(array("my" => "query")), $rp); var_dump($cursor); } ?> ===DONE=== --EXPECTF-- object(MongoDB\Driver\Cursor)#%d (%d) { ["cursor"]=> array(%d) { ["stamp"]=> int(0) ["is_command"]=> bool(false) ["sent"]=> bool(true) ["done"]=> bool(false) ["end_of_event"]=> bool(false) ["in_exhaust"]=> bool(false) ["has_fields"]=> bool(false) ["query"]=> object(stdClass)#%d (%d) { ["find"]=> string(%d) "%s" ["filter"]=> object(stdClass)#%d (%d) { ["my"]=> string(5) "query" } } ["fields"]=> object(stdClass)#%d (0) { } ["read_preference"]=> array(2) { ["mode"]=> int(1) ["tags"]=> array(0) { } } ["flags"]=> int(0) ["skip"]=> int(0) ["limit"]=> int(0) ["count"]=> int(1) ["batch_size"]=> int(0) ["ns"]=> string(%d) "%s" } ["server_id"]=> int(1) } object(MongoDB\Driver\Cursor)#%d (%d) { ["cursor"]=> array(%d) { ["stamp"]=> int(0) ["is_command"]=> bool(false) ["sent"]=> bool(true) ["done"]=> bool(false) ["end_of_event"]=> bool(false) ["in_exhaust"]=> bool(false) ["has_fields"]=> bool(false) ["query"]=> object(stdClass)#%d (%d) { ["find"]=> string(%d) "%s" ["filter"]=> object(stdClass)#%d (%d) { ["my"]=> string(5) "query" } } ["fields"]=> object(stdClass)#%d (0) { } ["read_preference"]=> array(2) { ["mode"]=> int(5) ["tags"]=> array(0) { } } ["flags"]=> int(0) ["skip"]=> int(0) ["limit"]=> int(0) ["count"]=> int(1) ["batch_size"]=> int(0) ["ns"]=> string(%d) "%s" } ["server_id"]=> int(1) } object(MongoDB\Driver\Cursor)#%d (%d) { ["cursor"]=> array(%d) { ["stamp"]=> int(0) ["is_command"]=> bool(false) ["sent"]=> bool(true) ["done"]=> bool(false) ["end_of_event"]=> bool(false) ["in_exhaust"]=> bool(false) ["has_fields"]=> bool(false) ["query"]=> object(stdClass)#%d (%d) { ["find"]=> string(%d) "%s" ["filter"]=> object(stdClass)#%d (%d) { ["my"]=> string(5) "query" } } ["fields"]=> object(stdClass)#%d (0) { } ["read_preference"]=> array(2) { ["mode"]=> int(2) ["tags"]=> array(0) { } } ["flags"]=> int(0) ["skip"]=> int(0) ["limit"]=> int(0) ["count"]=> int(1) ["batch_size"]=> int(0) ["ns"]=> string(%d) "%s" } ["server_id"]=> int(1) } object(MongoDB\Driver\Cursor)#%d (%d) { ["cursor"]=> array(%d) { ["stamp"]=> int(0) ["is_command"]=> bool(false) ["sent"]=> bool(true) ["done"]=> bool(false) ["end_of_event"]=> bool(false) ["in_exhaust"]=> bool(false) ["has_fields"]=> bool(false) ["query"]=> object(stdClass)#%d (%d) { ["find"]=> string(%d) "%s" ["filter"]=> object(stdClass)#%d (%d) { ["my"]=> string(5) "query" } } ["fields"]=> object(stdClass)#%d (0) { } ["read_preference"]=> array(2) { ["mode"]=> int(6) ["tags"]=> array(0) { } } ["flags"]=> int(0) ["skip"]=> int(0) ["limit"]=> int(0) ["count"]=> int(1) ["batch_size"]=> int(0) ["ns"]=> string(%d) "%s" } ["server_id"]=> int(1) } object(MongoDB\Driver\Cursor)#%d (%d) { ["cursor"]=> array(%d) { ["stamp"]=> int(0) ["is_command"]=> bool(false) ["sent"]=> bool(true) ["done"]=> bool(false) ["end_of_event"]=> bool(false) ["in_exhaust"]=> bool(false) ["has_fields"]=> bool(false) ["query"]=> object(stdClass)#%d (%d) { ["find"]=> string(%d) "%s" ["filter"]=> object(stdClass)#%d (%d) { ["my"]=> string(5) "query" } } ["fields"]=> object(stdClass)#%d (0) { } ["read_preference"]=> array(2) { ["mode"]=> int(10) ["tags"]=> array(0) { } } ["flags"]=> int(0) ["skip"]=> int(0) ["limit"]=> int(0) ["count"]=> int(1) ["batch_size"]=> int(0) ["ns"]=> string(%d) "%s" } ["server_id"]=> int(1) } ===DONE=== mongodb-1.1.5/tests/readPreference/readpreference-ctor-001.phpt0000664000175000017500000000162412673034026024177 0ustar jmikolajmikola--TEST-- MongoDB\Driver\ReadPreference construction --SKIPIF-- --FILE-- "one")))); var_dump(new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_PRIMARY, array())); ?> ===DONE=== --EXPECTF-- object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> int(1) ["tags"]=> array(0) { } } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> int(2) ["tags"]=> array(1) { [0]=> array(1) { ["tag"]=> string(3) "one" } } } object(MongoDB\Driver\ReadPreference)#%d (%d) { ["mode"]=> int(1) ["tags"]=> array(0) { } } ===DONE=== mongodb-1.1.5/tests/readPreference/readpreference-ctor_error-001.phpt0000664000175000017500000000134112673034026025404 0ustar jmikolajmikola--TEST-- MongoDB\Driver\ReadPreference construction (invalid arguments) --SKIPIF-- --FILE-- "one"))); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; echo throws(function() { new MongoDB\Driver\ReadPreference(42); }, 'MongoDB\Driver\Exception\InvalidArgumentException'), "\n"; ?> ===DONE=== --EXPECTF-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Invalid tagSets OK: Got MongoDB\Driver\Exception\InvalidArgumentException Invalid mode: 42 ===DONE=== mongodb-1.1.5/tests/readPreference/readpreference-getMode-001.phpt0000664000175000017500000000122412673034026024610 0ustar jmikolajmikola--TEST-- MongoDB\Driver\ReadPreference::getMode() --SKIPIF-- --FILE-- getMode()); } ?> ===DONE=== --EXPECT-- int(1) int(5) int(2) int(6) int(10) ===DONE=== mongodb-1.1.5/tests/readPreference/readpreference-getTagSets-001.phpt0000664000175000017500000000156412673034026025305 0ustar jmikolajmikola--TEST-- MongoDB\Driver\ReadPreference::getMode() --SKIPIF-- --FILE-- 'ny'), array()), array(array('dc' => 'ny'), array('dc' => 'sf', 'use' => 'reporting'), array()), ); foreach ($tests as $test) { $rp = new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY_PREFERRED, $test); var_dump($rp->getTagSets()); } ?> ===DONE=== --EXPECT-- array(0) { } array(0) { } array(2) { [0]=> array(1) { ["dc"]=> string(2) "ny" } [1]=> array(0) { } } array(3) { [0]=> array(1) { ["dc"]=> string(2) "ny" } [1]=> array(2) { ["dc"]=> string(2) "sf" ["use"]=> string(9) "reporting" } [2]=> array(0) { } } ===DONE=== mongodb-1.1.5/tests/readPreference/readpreference_error-001.phpt0000664000175000017500000000063512673034026024444 0ustar jmikolajmikola--TEST-- MongoDB\Driver\ReadPreference cannot be extended --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- Fatal error: Class MyReadPreference may not inherit from final class (MongoDB\Driver\ReadPreference) in %s on line %d mongodb-1.1.5/tests/server/server-constants.phpt0000664000175000017500000000133712673034026021677 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Server constants --SKIPIF-- --FILE-- ===DONE=== --EXPECT-- int(0) int(1) int(2) int(3) int(4) int(5) int(6) int(7) int(8) ===DONE=== mongodb-1.1.5/tests/server/server-construct-001.phpt0000664000175000017500000000112612673034026022201 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Server::__construct() --SKIPIF-- --FILE-- insert(array('foo' => 'bar')); $server = $manager->executeBulkWrite(NS, $bulk)->getServer(); var_dump($server->getHost() == $parsed["host"]); var_dump($server->getPort() == $parsed["port"]); ?> ===DONE=== --EXPECTF-- bool(true) bool(true) ===DONE=== mongodb-1.1.5/tests/server/server-debug.phpt0000664000175000017500000000221212673034026020742 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Server debugInfo --SKIPIF-- --FILE-- executeQuery(NS, new MongoDB\Driver\Query(array()))->getServer(); var_dump($server); ?> ===DONE=== --EXPECTF-- object(MongoDB\Driver\Server)#%d (%d) { ["host"]=> string(%d) "%s" ["port"]=> int(%d) ["type"]=> int(1) ["is_primary"]=> bool(false) ["is_secondary"]=> bool(false) ["is_arbiter"]=> bool(false) ["is_hidden"]=> bool(false) ["is_passive"]=> bool(false) ["last_is_master"]=> array(8) { ["ismaster"]=> bool(true) ["maxBsonObjectSize"]=> int(16777216) ["maxMessageSizeBytes"]=> int(48000000) ["maxWriteBatchSize"]=> int(1000) ["localTime"]=> object(%s\UTCDateTime)#%d (%d) { ["milliseconds"]=> %r(int\(\d+\)|string\(\d+\) "\d+")%r } ["maxWireVersion"]=> int(%d) ["minWireVersion"]=> int(0) ["ok"]=> float(1) } ["round_trip_time"]=> int(%d) } ===DONE=== mongodb-1.1.5/tests/server/server-errors.phpt0000664000175000017500000000364012673034026021176 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Server::executeQuery() with sort and empty filter --SKIPIF-- --FILE-- executeQuery(NS, new MongoDB\Driver\Query(array()))->getServer(); var_dump($server->getHost(true)); var_dump($server->getTags(true)); var_dump($server->getInfo(true)); var_dump($server->getLatency(true)); var_dump($server->getPort(true)); var_dump($server->getType(true)); var_dump($server->isPrimary(true)); var_dump($server->isSecondary(true)); var_dump($server->isArbiter(true)); var_dump($server->isHidden(true)); var_dump($server->isPassive(true)); ?> ===DONE=== --EXPECTF-- Warning: MongoDB\Driver\Server::getHost() expects exactly 0 parameters, 1 given in %s on line %d NULL Warning: MongoDB\Driver\Server::getTags() expects exactly 0 parameters, 1 given in %s on line %d NULL Warning: MongoDB\Driver\Server::getInfo() expects exactly 0 parameters, 1 given in %s on line %d NULL Warning: MongoDB\Driver\Server::getLatency() expects exactly 0 parameters, 1 given in %s on line %d NULL Warning: MongoDB\Driver\Server::getPort() expects exactly 0 parameters, 1 given in %s on line %d NULL Warning: MongoDB\Driver\Server::getType() expects exactly 0 parameters, 1 given in %s on line %d NULL Warning: MongoDB\Driver\Server::isPrimary() expects exactly 0 parameters, 1 given in %s on line %d NULL Warning: MongoDB\Driver\Server::isSecondary() expects exactly 0 parameters, 1 given in %s on line %d NULL Warning: MongoDB\Driver\Server::isArbiter() expects exactly 0 parameters, 1 given in %s on line %d NULL Warning: MongoDB\Driver\Server::isHidden() expects exactly 0 parameters, 1 given in %s on line %d NULL Warning: MongoDB\Driver\Server::isPassive() expects exactly 0 parameters, 1 given in %s on line %d NULL ===DONE=== mongodb-1.1.5/tests/server/server-executeBulkWrite-001.phpt0000664000175000017500000000401712673034026023452 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Server::executeBulkWrite() --SKIPIF-- --FILE-- executeQuery(NS, new MongoDB\Driver\Query(array()))->getServer(); $bulk = new MongoDB\Driver\BulkWrite(); $bulk->insert(array('_id' => 1, 'x' => 1)); $bulk->insert(array('_id' => 2, 'x' => 2)); $bulk->update(array('x' => 2), array('$set' => array('x' => 1)), array("limit" => 1, "upsert" => false)); $bulk->update(array('_id' => 3), array('$set' => array('x' => 3)), array("limit" => 1, "upsert" => true)); $bulk->delete(array('x' => 1), array("limit" => 1)); $result = $server->executeBulkWrite(NS, $bulk); printf("WriteResult.server is the same: %s\n", $server == $result->getServer() ? 'yes' : 'no'); echo "\n===> WriteResult\n"; printWriteResult($result); var_dump($result); echo "\n===> Collection\n"; $cursor = $server->executeQuery(NS, new MongoDB\Driver\Query(array())); var_dump(iterator_to_array($cursor)); ?> ===DONE=== --EXPECTF-- WriteResult.server is the same: yes ===> WriteResult server: %s:%d insertedCount: 2 matchedCount: 1 modifiedCount: 1 upsertedCount: 1 deletedCount: 1 upsertedId[3]: int(3) object(MongoDB\Driver\WriteResult)#%d (%d) { ["nInserted"]=> int(2) ["nMatched"]=> int(1) ["nModified"]=> int(1) ["nRemoved"]=> int(1) ["nUpserted"]=> int(1) ["upsertedIds"]=> array(1) { [0]=> array(%d) { ["index"]=> int(3) ["_id"]=> int(3) } } ["writeErrors"]=> array(0) { } ["writeConcernError"]=> NULL ["writeConcern"]=> array(%d) { ["w"]=> NULL ["wmajority"]=> bool(false) ["wtimeout"]=> int(0) ["journal"]=> NULL } } ===> Collection array(2) { [0]=> object(stdClass)#%d (%d) { ["_id"]=> int(2) ["x"]=> int(1) } [1]=> object(stdClass)#%d (%d) { ["_id"]=> int(3) ["x"]=> int(3) } } ===DONE=== mongodb-1.1.5/tests/server/server-executeBulkWrite-002.phpt0000664000175000017500000000151612673034026023454 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Server::executeBulkWrite() with write concern (standalone) --SKIPIF-- --FILE-- selectServer(new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_PRIMARY)); $writeConcerns = array(0, 1); foreach ($writeConcerns as $writeConcern) { $bulk = new MongoDB\Driver\BulkWrite(); $bulk->insert(array('wc' => $writeConcern)); $result = $primary->executeBulkWrite(NS, $bulk, new MongoDB\Driver\WriteConcern($writeConcern)); var_dump($result->isAcknowledged()); var_dump($result->getInsertedCount()); } ?> ===DONE=== --EXPECT-- bool(false) int(0) bool(true) int(1) ===DONE=== mongodb-1.1.5/tests/server/server-executeBulkWrite-003.phpt0000664000175000017500000000164412673034026023457 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Server::executeBulkWrite() with write concern (replica set primary) --SKIPIF-- --FILE-- selectServer(new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_PRIMARY)); $writeConcerns = array(0, 1, 2, MongoDB\Driver\WriteConcern::MAJORITY); foreach ($writeConcerns as $wc) { $bulk = new MongoDB\Driver\BulkWrite(); $bulk->insert(array('wc' => $wc)); $result = $server->executeBulkWrite(NS, $bulk, new MongoDB\Driver\WriteConcern($wc)); var_dump($result->isAcknowledged()); var_dump($result->getInsertedCount()); } ?> ===DONE=== --EXPECT-- bool(false) int(0) bool(true) int(1) bool(true) int(1) bool(true) int(1) ===DONE=== mongodb-1.1.5/tests/server/server-executeBulkWrite-004.phpt0000664000175000017500000000245112673034026023455 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Server::executeBulkWrite() with write concern (replica set secondary) --SKIPIF-- --FILE-- selectServer(new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY)); $bulk = new MongoDB\Driver\BulkWrite(); $bulk->insert(array('wc' => 0)); $result = $server->executeBulkWrite(NS, $bulk, new MongoDB\Driver\WriteConcern(0)); var_dump($result->isAcknowledged()); var_dump($result->getInsertedCount()); $writeConcerns = array(1, 2, MongoDB\Driver\WriteConcern::MAJORITY); foreach ($writeConcerns as $wc) { $bulk = new MongoDB\Driver\BulkWrite(); $bulk->insert(array('wc' => $wc)); echo throws(function() use ($server, $bulk, $wc) { $server->executeBulkWrite(NS, $bulk, new MongoDB\Driver\WriteConcern($wc)); }, "MongoDB\Driver\Exception\RuntimeException"), "\n"; } ?> ===DONE=== --EXPECT-- bool(false) int(0) OK: Got MongoDB\Driver\Exception\RuntimeException not master OK: Got MongoDB\Driver\Exception\RuntimeException not master OK: Got MongoDB\Driver\Exception\RuntimeException not master ===DONE=== mongodb-1.1.5/tests/server/server-executeBulkWrite-005.phpt0000664000175000017500000000217212673034026023456 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Server::executeBulkWrite() with write concern (replica set secondary, local DB) --SKIPIF-- --FILE-- selectServer(new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_SECONDARY)); /* The server ignores write concerns with w>2 for writes to the local database, * so we won't test behavior for w=2 and w=majority. */ $writeConcerns = array(0, 1); foreach ($writeConcerns as $wc) { $bulk = new MongoDB\Driver\BulkWrite(); $bulk->insert(array('wc' => $wc)); $result = $server->executeBulkWrite('local.' . COLLECTION_NAME, $bulk, new MongoDB\Driver\WriteConcern($wc)); var_dump($result->isAcknowledged()); var_dump($result->getInsertedCount()); } $command = new MongoDB\Driver\Command(array('drop' => COLLECTION_NAME)); $server->executeCommand('local', $command); ?> ===DONE=== --EXPECT-- bool(false) int(0) bool(true) int(1) ===DONE=== mongodb-1.1.5/tests/server/server-executeCommand-001.phpt0000664000175000017500000000320512673034026023116 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Server::executeCommand() --SKIPIF-- --FILE-- executeQuery(NS, new MongoDB\Driver\Query(array()))->getServer(); $command = new MongoDB\Driver\Command(array('ping' => 1)); $result = $server->executeCommand(DATABASE_NAME, $command); var_dump($result instanceof MongoDB\Driver\Cursor); var_dump($result); echo "\nDumping response document:\n"; var_dump(current($result->toArray())); var_dump($server == $result->getServer()); ?> ===DONE=== --EXPECTF-- bool(true) object(MongoDB\Driver\Cursor)#%d (%d) { ["cursor"]=> array(%d) { ["stamp"]=> int(0) ["is_command"]=> bool(true) ["sent"]=> bool(true) ["done"]=> bool(false) ["end_of_event"]=> bool(false) ["in_exhaust"]=> bool(false) ["has_fields"]=> bool(false) ["query"]=> object(stdClass)#%d (1) { ["ping"]=> int(1) } ["fields"]=> object(stdClass)#%d (0) { } ["read_preference"]=> array(2) { ["mode"]=> int(1) ["tags"]=> array(0) { } } ["flags"]=> int(0) ["skip"]=> int(0) ["limit"]=> int(1) ["count"]=> int(1) ["batch_size"]=> int(0) ["ns"]=> string(11) "phongo.$cmd" ["current_doc"]=> object(stdClass)#%d (1) { ["ok"]=> float(1) } } ["server_id"]=> int(1) } Dumping response document: object(stdClass)#%d (1) { ["ok"]=> float(1) } bool(true) ===DONE=== mongodb-1.1.5/tests/server/server-executeCommand-002.phpt0000664000175000017500000000356112673034026023124 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Server::executeCommand() takes a read preference --SKIPIF-- --FILE-- selectServer($rp); $command = new MongoDB\Driver\Command(array('profile' => 2)); $cursor = $secondary->executeCommand(DATABASE_NAME, $command); $result = current($cursor->toArray()); printf("Set profile level to 2 successfully: %s\n", (empty($result->ok) ? 'no' : 'yes')); $command = new MongoDB\Driver\Command(array( 'aggregate' => COLLECTION_NAME, 'pipeline' => array(array('$match' => array('x' => 1))), )); $secondary->executeCommand(DATABASE_NAME, $command, $rp); $query = new MongoDB\Driver\Query( array( 'op' => 'command', 'ns' => DATABASE_NAME . '.' . COLLECTION_NAME, ), array( 'sort' => array('ts' => -1), 'limit' => 1, ) ); $cursor = $secondary->executeQuery(DATABASE_NAME . '.system.profile', $query, $rp); $profileEntry = current($cursor->toArray()); var_dump($profileEntry->command); $command = new MongoDB\Driver\Command(array('profile' => 0)); $cursor = $secondary->executeCommand(DATABASE_NAME, $command); $result = current($cursor->toArray()); printf("Set profile level to 0 successfully: %s\n", (empty($result->ok) ? 'no' : 'yes')); ?> ===DONE=== --EXPECTF-- Set profile level to 2 successfully: yes object(stdClass)#%d (%d) { ["aggregate"]=> string(32) "server_server_executeCommand_002" ["pipeline"]=> array(1) { [0]=> object(stdClass)#%d (%d) { ["$match"]=> object(stdClass)#%d (%d) { ["x"]=> int(1) } } } } Set profile level to 0 successfully: yes ===DONE=== mongodb-1.1.5/tests/server/server-executeCommand_error-001.phpt0000664000175000017500000000150412673034026024327 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Server::executeCommand() with conflicting read preference for secondary --SKIPIF-- --FILE-- selectServer($rp); echo throws(function() use ($secondary) { $rp = new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_PRIMARY); $secondary->executeCommand(NS, new MongoDB\Driver\Command(array('ping' => 1)), $rp); }, "MongoDB\Driver\Exception\RuntimeException"), "\n"; ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\RuntimeException not master and slaveOk=false ===DONE=== mongodb-1.1.5/tests/server/server-executeQuery-001.phpt0000664000175000017500000000211612673034026022645 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Server::executeQuery() with filter and projection --SKIPIF-- --FILE-- executeQuery(NS, new MongoDB\Driver\Query(array()))->getServer(); // load fixtures for test $bulk = new \MongoDB\Driver\BulkWrite(); $bulk->insert(array('_id' => 1, 'x' => 2, 'y' => 3)); $bulk->insert(array('_id' => 2, 'x' => 3, 'y' => 4)); $bulk->insert(array('_id' => 3, 'x' => 4, 'y' => 5)); $server->executeBulkWrite(NS, $bulk); $query = new MongoDB\Driver\Query(array('x' => 3), array('projection' => array('y' => 1))); $cursor = $server->executeQuery(NS, $query); var_dump($cursor instanceof MongoDB\Driver\Cursor); var_dump($server == $cursor->getServer()); var_dump(iterator_to_array($cursor)); ?> ===DONE=== --EXPECTF-- bool(true) bool(true) array(1) { [0]=> object(stdClass)#%d (2) { ["_id"]=> int(2) ["y"]=> int(4) } } ===DONE=== mongodb-1.1.5/tests/server/server-executeQuery-002.phpt0000664000175000017500000000244212673034026022650 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Server::executeQuery() with sort and empty filter --SKIPIF-- --FILE-- executeQuery(NS, new MongoDB\Driver\Query(array()))->getServer(); // load fixtures for test $bulk = new \MongoDB\Driver\BulkWrite(); $bulk->insert(array('_id' => 1, 'x' => 2, 'y' => 3)); $bulk->insert(array('_id' => 2, 'x' => 3, 'y' => 4)); $bulk->insert(array('_id' => 3, 'x' => 4, 'y' => 5)); $server->executeBulkWrite(NS, $bulk); $query = new MongoDB\Driver\Query(array(), array('sort' => array('_id' => -1))); $cursor = $server->executeQuery(NS, $query); var_dump($cursor instanceof MongoDB\Driver\Cursor); var_dump($server == $cursor->getServer()); var_dump(iterator_to_array($cursor)); ?> ===DONE=== --EXPECTF-- bool(true) bool(true) array(3) { [0]=> object(stdClass)#%d (3) { ["_id"]=> int(3) ["x"]=> int(4) ["y"]=> int(5) } [1]=> object(stdClass)#%d (3) { ["_id"]=> int(2) ["x"]=> int(3) ["y"]=> int(4) } [2]=> object(stdClass)#%d (3) { ["_id"]=> int(1) ["x"]=> int(2) ["y"]=> int(3) } } ===DONE=== mongodb-1.1.5/tests/server/server-executeQuery-003.phpt0000664000175000017500000000246412673034026022655 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Server::executeQuery() with modifiers and empty filter --SKIPIF-- --FILE-- executeQuery(NS, new MongoDB\Driver\Query(array()))->getServer(); // load fixtures for test $bulk = new \MongoDB\Driver\BulkWrite(); $bulk->insert(array('_id' => 1, 'x' => 2, 'y' => 3)); $bulk->insert(array('_id' => 2, 'x' => 3, 'y' => 4)); $bulk->insert(array('_id' => 3, 'x' => 4, 'y' => 5)); $server->executeBulkWrite(NS, $bulk); $query = new MongoDB\Driver\Query(array(), array('modifiers' => array('$comment' => 'foo'))); $cursor = $server->executeQuery(NS, $query); var_dump($cursor instanceof MongoDB\Driver\Cursor); var_dump($server == $cursor->getServer()); var_dump(iterator_to_array($cursor)); ?> ===DONE=== --EXPECTF-- bool(true) bool(true) array(3) { [0]=> object(stdClass)#%d (3) { ["_id"]=> int(1) ["x"]=> int(2) ["y"]=> int(3) } [1]=> object(stdClass)#%d (3) { ["_id"]=> int(2) ["x"]=> int(3) ["y"]=> int(4) } [2]=> object(stdClass)#%d (3) { ["_id"]=> int(3) ["x"]=> int(4) ["y"]=> int(5) } } ===DONE=== mongodb-1.1.5/tests/server/server-executeQuery-004.phpt0000664000175000017500000000131612673034026022651 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Server::executeQuery() finds no matching documents --SKIPIF-- --FILE-- executeQuery(NS, new MongoDB\Driver\Query(array()))->getServer(); $bulk = new \MongoDB\Driver\BulkWrite(); $bulk->insert(array('_id' => 1, 'x' => 1)); $bulk->insert(array('_id' => 2, 'x' => 1)); $server->executeBulkWrite(NS, $bulk); $cursor = $server->executeQuery(NS, new MongoDB\Driver\Query(array("x" => 2))); var_dump(iterator_to_array($cursor)); ?> ===DONE=== --EXPECT-- array(0) { } ===DONE=== mongodb-1.1.5/tests/server/server-executeQuery-005.phpt0000664000175000017500000000317312673034026022655 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Server::executeQuery() takes a read preference (OP_QUERY) --SKIPIF-- --FILE-- selectServer($rp); $command = new MongoDB\Driver\Command(array('profile' => 2)); $cursor = $secondary->executeCommand(DATABASE_NAME, $command); $result = current($cursor->toArray()); printf("Set profile level to 2 successfully: %s\n", (empty($result->ok) ? 'no' : 'yes')); if (empty($result->ok)) { exit("Could not set profile level\n"); } $secondary->executeQuery(NS, new MongoDB\Driver\Query(array("x" => 1)), $rp); $query = new MongoDB\Driver\Query( array( 'op' => 'query', 'ns' => NS, ), array( 'sort' => array('ts' => -1), 'limit' => 1, ) ); $cursor = $secondary->executeQuery(DATABASE_NAME . '.system.profile', $query, $rp); $profileEntry = current($cursor->toArray()); var_dump($profileEntry->query); $command = new MongoDB\Driver\Command(array('profile' => 0)); $cursor = $secondary->executeCommand(DATABASE_NAME, $command); $result = current($cursor->toArray()); printf("Set profile level to 0 successfully: %s\n", (empty($result->ok) ? 'no' : 'yes')); ?> ===DONE=== --EXPECTF-- Set profile level to 2 successfully: yes object(stdClass)#%d (%d) { ["$query"]=> object(stdClass)#%d (1) { ["x"]=> int(1) } } Set profile level to 0 successfully: yes ===DONE=== mongodb-1.1.5/tests/server/server-executeQuery-006.phpt0000664000175000017500000000323012673034026022650 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Server::executeQuery() takes a read preference (find command) --SKIPIF-- --FILE-- selectServer($rp); $command = new MongoDB\Driver\Command(array('profile' => 2)); $cursor = $secondary->executeCommand(DATABASE_NAME, $command); $result = current($cursor->toArray()); printf("Set profile level to 2 successfully: %s\n", (empty($result->ok) ? 'no' : 'yes')); if (empty($result->ok)) { exit("Could not set profile level\n"); } $secondary->executeQuery(NS, new MongoDB\Driver\Query(array("x" => 1)), $rp); $query = new MongoDB\Driver\Query( array( 'op' => 'query', 'ns' => NS, ), array( 'sort' => array('ts' => -1), 'limit' => 1, ) ); $cursor = $secondary->executeQuery(DATABASE_NAME . '.system.profile', $query, $rp); $profileEntry = current($cursor->toArray()); var_dump($profileEntry->query); $command = new MongoDB\Driver\Command(array('profile' => 0)); $cursor = $secondary->executeCommand(DATABASE_NAME, $command); $result = current($cursor->toArray()); printf("Set profile level to 0 successfully: %s\n", (empty($result->ok) ? 'no' : 'yes')); ?> ===DONE=== --EXPECTF-- Set profile level to 2 successfully: yes object(stdClass)#%d (%d) { ["find"]=> string(%d) "%s" ["filter"]=> object(stdClass)#%d (1) { ["x"]=> int(1) } } Set profile level to 0 successfully: yes ===DONE=== mongodb-1.1.5/tests/server/server-executeQuery-007.phpt0000664000175000017500000000223312673034026022653 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Server::executeQuery() with negative limit returns a single batch --SKIPIF-- --FILE-- executeQuery(NS, new MongoDB\Driver\Query(array()))->getServer(); // load fixtures for test $bulk = new \MongoDB\Driver\BulkWrite(); $bulk->insert(['_id' => 1, 'x' => 2, 'y' => 3]); $bulk->insert(['_id' => 2, 'x' => 3, 'y' => 4]); $bulk->insert(['_id' => 3, 'x' => 4, 'y' => 5]); $server->executeBulkWrite(NS, $bulk); $query = new MongoDB\Driver\Query([], ['limit' => -2]); $cursor = $server->executeQuery(NS, $query); var_dump($cursor instanceof MongoDB\Driver\Cursor); var_dump($server == $cursor->getServer()); var_dump(iterator_to_array($cursor)); ?> ===DONE=== --EXPECTF-- bool(true) bool(true) array(2) { [0]=> object(stdClass)#%d (3) { ["_id"]=> int(1) ["x"]=> int(2) ["y"]=> int(3) } [1]=> object(stdClass)#%d (3) { ["_id"]=> int(2) ["x"]=> int(3) ["y"]=> int(4) } } ===DONE=== mongodb-1.1.5/tests/server/server-executeQuery_error-001.phpt0000664000175000017500000000147312673034026024063 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Server::executeQuery() with conflicting read preference for secondary --SKIPIF-- --FILE-- selectServer($rp); echo throws(function() use ($secondary) { $rp = new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_PRIMARY); $secondary->executeQuery(NS, new MongoDB\Driver\Query(array("x" => 1)), $rp); }, "MongoDB\Driver\Exception\RuntimeException"), "\n"; ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\RuntimeException not master and slaveOk=false ===DONE=== mongodb-1.1.5/tests/server/server_error-001.phpt0000664000175000017500000000056512673034026021376 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Server cannot be extended --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- Fatal error: Class MyServer may not inherit from final class (MongoDB\Driver\Server) in %s on line %d mongodb-1.1.5/tests/standalone/bug0159.phpt0000664000175000017500000000102012673034026020262 0ustar jmikolajmikola--TEST-- PHPC-159: Memleak on failed path resolving --SKIPIF-- --FILE-- executeQuery("foo.bar", new MongoDB\Driver\Query(array())); } catch(Exception $e) {} ?> ===DONE=== --EXPECT-- ===DONE=== mongodb-1.1.5/tests/standalone/bug0166.phpt0000664000175000017500000000142312673034026020267 0ustar jmikolajmikola--TEST-- Disable serialization of objects --SKIPIF-- --FILE-- ===DONE=== --EXPECT-- bool(false) OK: Got Exception ===DONE=== mongodb-1.1.5/tests/standalone/bug0231.phpt0000664000175000017500000000141412673034026020260 0ustar jmikolajmikola--TEST-- Multiple managers sharing streams: Using stream after closing manager --SKIPIF-- --FILE-- 1)); $retval = $manager->executeCommand("admin", $listdatabases); $retval = $manager2->executeCommand("admin", $listdatabases); foreach($retval as $database) { } $manager = null; $retval = $manager2->executeCommand("admin", $listdatabases); foreach($retval as $database) { } echo "All Good!\n"; ?> ===DONE=== --EXPECT-- All Good! ===DONE=== mongodb-1.1.5/tests/standalone/bug0357.phpt0000664000175000017500000000111412673034026020266 0ustar jmikolajmikola--TEST-- PHPC-357: The exception for "invalid namespace" does not list the broken name --SKIPIF-- --FILE-- executeQuery( 'demo', $c ); }, "MongoDB\\Driver\\Exception\\InvalidArgumentException"), "\n"; ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Invalid namespace provided: demo ===DONE=== mongodb-1.1.5/tests/standalone/bug0487-001.phpt0000664000175000017500000000116612673034026020577 0ustar jmikolajmikola--TEST-- PHPC-487: check_closed stream handler should not report open socket as closed --SKIPIF-- --FILE-- insert(['x' => 1]); $wr = $m->executeBulkWrite(NS, $bulk); var_dump($wr->getInsertedCount()); sleep(1); $bulk = new MongoDB\Driver\BulkWrite; $bulk->insert(['x' => 1]); $wr = $m->executeBulkWrite(NS, $bulk); var_dump($wr->getInsertedCount()); ?> ===DONE=== --EXPECT-- int(1) int(1) ===DONE=== mongodb-1.1.5/tests/standalone/bug0487-002.phpt0000664000175000017500000000447512673034026020606 0ustar jmikolajmikola--TEST-- PHPC-487: check_closed stream handler should report closed socket as closed --SKIPIF-- --FILE-- array( "method" => "DELETE", "timeout" => 60, "header" => "Accept: application/json\r\n" . "Content-type: application/x-www-form-urlencoded", "ignore_errors" => true, ), ); $context = stream_context_create($opts); $out = file_get_contents($url, false, $context); } function mo_post($url, $body) { global $KILLLIST; $url = getMOUri() . $url; $opts = array("http" => array( "method" => "POST", "timeout" => 60, "header" => "Accept: application/json\r\n" . "Content-type: application/x-www-form-urlencoded", "content" => json_encode($body), "ignore_errors" => true, ), ); $context = stream_context_create($opts); $out = file_get_contents($url, false, $context); $array = json_decode($out, true); if ($array && !empty($array["mongodb_uri"])) { $KILLLIST[] = $array["id"]; return $array["mongodb_uri"]; } } $KILLLIST = array(); $dsn = mo_post("/servers", [ 'id' => 'serverA', 'name' => 'mongod', ]); $m = new MongoDB\Driver\Manager($dsn); $bulk = new MongoDB\Driver\BulkWrite; $bulk->insert(['x' => 1]); $wr = $m->executeBulkWrite(NS, $bulk); var_dump($wr->getInsertedCount()); mo_post("/servers/serverA", ['action' => 'stop']); echo throws(function() use ($m) { $bulk = new MongoDB\Driver\BulkWrite; $bulk->insert(['x' => 1]); $wr = $m->executeBulkWrite(NS, $bulk); var_dump($wr->getInsertedCount()); }, 'MongoDB\Driver\Exception\RuntimeException'), "\n"; mo_post("/servers/serverA", ['action' => 'restart']); $bulk = new MongoDB\Driver\BulkWrite; $bulk->insert(['x' => 1]); $wr = $m->executeBulkWrite(NS, $bulk); var_dump($wr->getInsertedCount()); foreach($KILLLIST as $id) { mo_delete("/servers/$id"); } ?> ===DONE=== --EXPECTF-- int(1) OK: Got MongoDB\Driver\Exception\RuntimeException Failed to read 4 bytes from socket within 300000 milliseconds. int(1) ===DONE=== mongodb-1.1.5/tests/standalone/bug0545.phpt0000664000175000017500000000611112673034026020267 0ustar jmikolajmikola--TEST-- PHPC-545: Update does not serialize embedded Persistable's __pclass field --SKIPIF-- --FILE-- $value) { $this->{$name} = $value; } } } class Page implements MongoDB\BSON\Persistable { public function bsonSerialize() { $data = get_object_vars($this); return $data; } public function bsonUnserialize(array $data) { foreach ($data as $name => $value) { $this->{$name} = $value; } } } // Aux $manager = new MongoDB\Driver\Manager(STANDALONE); $wc = new MongoDB\Driver\WriteConcern(MongoDB\Driver\WriteConcern::MAJORITY); // Create $book = new Book(); $book->title = 'Unnameable'; $book->pages = []; $page1 = new Page(); $page1->content = 'Lorem ipsum'; $book->pages[] = $page1; $bulk = new MongoDB\Driver\BulkWrite; $bulk->insert($book); $result = $manager->executeBulkWrite(NS, $bulk, $wc); printf("Inserted %d document(s)\n", $result->getInsertedCount()); // Read $query = new MongoDB\Driver\Query(['title' => $book->title]); $cursor = $manager->executeQuery(NS, $query); $bookAfterInsert = $cursor->toArray()[0]; // Update $bookAfterInsert->description = 'An interesting document'; $page2 = new Page(); $page2->content = 'Dolor sit amet'; $bookAfterInsert->pages[] = $page2; $bulk = new MongoDB\Driver\BulkWrite; $bulk->update(['title' => $bookAfterInsert->title], $bookAfterInsert); $result = $manager->executeBulkWrite(NS, $bulk, $wc); printf("Modified %d document(s)\n", $result->getModifiedCount()); // Read (again) $query = new MongoDB\Driver\Query(['title' => $bookAfterInsert->title]); $cursor = $manager->executeQuery(NS, $query); $bookAfterUpdate = $cursor->toArray()[0]; var_dump($bookAfterUpdate); ?> ===DONE=== --EXPECTF-- Inserted 1 document(s) Modified 1 document(s) object(Book)#%d (%d) { ["_id"]=> object(MongoDB\BSON\ObjectID)#%d (%d) { ["oid"]=> string(24) "%s" } ["__pclass"]=> object(MongoDB\BSON\Binary)#%d (%d) { ["data"]=> string(4) "Book" ["type"]=> int(%d) } ["title"]=> string(10) "Unnameable" ["pages"]=> array(2) { [0]=> object(Page)#%d (%d) { ["__pclass"]=> object(MongoDB\BSON\Binary)#%d (%d) { ["data"]=> string(4) "Page" ["type"]=> int(%d) } ["content"]=> string(11) "Lorem ipsum" } [1]=> object(Page)#%d (%d) { ["__pclass"]=> object(MongoDB\BSON\Binary)#%d (%d) { ["data"]=> string(4) "Page" ["type"]=> int(%d) } ["content"]=> string(14) "Dolor sit amet" } } ["description"]=> string(23) "An interesting document" } ===DONE=== mongodb-1.1.5/tests/standalone/connectiontimeoutexception-001.phpt0000664000175000017500000000136512673034026025165 0ustar jmikolajmikola--TEST-- ConnectionTimeoutException: exceeding sockettimeoutms --SKIPIF-- --FILE-- 1, "w" => false, "secs" => 2, ); $command = new MongoDB\Driver\Command($cmd); throws(function() use ($manager, $command) { $result = $manager->executeCommand("admin", $command); var_dump($result->toArray()); }, "MongoDB\Driver\Exception\\ConnectionTimeoutException"); ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\ConnectionTimeoutException ===DONE=== mongodb-1.1.5/tests/standalone/executiontimeoutexception-001.phpt0000664000175000017500000000151712673034026025030 0ustar jmikolajmikola--TEST-- ExecutionTimeoutException: exceeding $maxTimeMS (queries) --SKIPIF-- --FILE-- "Smith, Carter and Buckridge"), array( 'projection' => array('_id' => 0, 'username' => 1), 'sort' => array('phoneNumber' => 1), 'modifiers' => array( '$maxTimeMS' => 1, ), )); failMaxTimeMS($manager); throws(function() use ($manager, $query) { $result = $manager->executeQuery(NS, $query); }, "MongoDB\Driver\Exception\ExecutionTimeoutException"); ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\ExecutionTimeoutException ===DONE=== mongodb-1.1.5/tests/standalone/executiontimeoutexception-002.phpt0000664000175000017500000000136612673034026025033 0ustar jmikolajmikola--TEST-- ExecutionTimeoutException: exceeding maxTimeMS (commands) --SKIPIF-- --FILE-- "collection", "query" => array("a" => 1), "maxTimeMS" => 100, ); $command = new MongoDB\Driver\Command($cmd); failMaxTimeMS($manager); throws(function() use ($manager, $command) { $result = $manager->executeCommand(DATABASE_NAME, $command); }, "MongoDB\Driver\Exception\ExecutionTimeoutException"); ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\ExecutionTimeoutException ===DONE=== mongodb-1.1.5/tests/standalone/manager-as-singleton.phpt0000664000175000017500000000266512673034026023221 0ustar jmikolajmikola--TEST-- PHPC-431: Segfault when using Manager through singleton class --SKIPIF-- --FILE-- Database = $Manager; } public static function getInstance() { if (static::$Instance == null) { static::$Instance = new Database(); } return static::$Instance; } public function query($scheme, $query) { return $this->Database->executeQuery($scheme, $query, new ReadPreference(ReadPreference::RP_PRIMARY)); } } class App { public function run() { $db = Database::getInstance(); $query = new Query(array()); $cursor = $db->query(DATABASE_NAME . ".scheme_info", $query); foreach ($cursor as $document) { echo $document->value; } $query = new Query(array()); $cursor = $db->query(DATABASE_NAME . ".domain", $query); foreach ($cursor as $document) { echo $document->hostname; } } } $App = new App(); $App->run(); echo "All done\n"; ?> ===DONE=== --EXPECT-- All done ===DONE=== mongodb-1.1.5/tests/standalone/query-errors.phpt0000664000175000017500000000244112673034026021655 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Query: Invalid types --SKIPIF-- --FILE-- "Smith, Carter and Buckridge"), array( "projection" => array("_id" => 0, "username" => 1), "sort" => array("phoneNumber" => 1), "modifiers" => "string", )); }, "MongoDB\Driver\Exception\InvalidArgumentException"); throws(function() { $query = new MongoDB\Driver\Query(array("company" => "Smith, Carter and Buckridge"), array( "projection" => array("_id" => 0, "username" => 1), "sort" => array("phoneNumber" => 1), "projection" => "string", )); }, "MongoDB\Driver\Exception\InvalidArgumentException"); throws(function() { $query = new MongoDB\Driver\Query(array("company" => "Smith, Carter and Buckridge"), array( "projection" => array("_id" => 0, "username" => 1), "sort" => "string" )); }, "MongoDB\Driver\Exception\InvalidArgumentException"); ?> ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException OK: Got MongoDB\Driver\Exception\InvalidArgumentException OK: Got MongoDB\Driver\Exception\InvalidArgumentException ===DONE=== mongodb-1.1.5/tests/standalone/update-multi-001.phpt0000664000175000017500000001161112673034026022105 0ustar jmikolajmikola--TEST-- PHPC-243: Manager::executeUpdate() & Bulk->update() w/o multi --SKIPIF-- --FILE-- insert(array('_id' => 1, 'x' => 1)); $bulk->insert(array('_id' => 2, 'x' => 2)); $bulk->insert(array('_id' => 3, 'x' => 2)); $bulk->insert(array('_id' => 4, 'x' => 2)); $bulk->insert(array('_id' => 5, 'x' => 1)); $bulk->insert(array('_id' => 6, 'x' => 1)); $manager->executeBulkWrite(NS, $bulk); $bulk = new \MongoDB\Driver\BulkWrite; $bulk->update( array('x' => 1), array('$set' => array('x' => 3)), array('multi' => false, 'upsert' => false) ); $result = $manager->executeBulkWrite(NS, $bulk); printf("Changed %d out of expected 1 (_id=1)\n", $result->getModifiedCount()); $bulk = new \MongoDB\Driver\BulkWrite; $bulk->update( array('x' => 1), array('$set' => array('x' => 2)), array('multi' => true, 'upsert' => false) ); $result = $manager->executeBulkWrite(NS, $bulk); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query(array())); var_dump(iterator_to_array($cursor)); printf("Changed %d out of expected 2, (_id=5, _id=6)\n", $result->getModifiedCount()); $bulk = new MongoDB\Driver\BulkWrite; $bulk->update( array('x' => 2), array('$set' => array('x' => 4)), array('multi' => false, 'upsert' => false) ); $result = $manager->executeBulkWrite(NS, $bulk); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query(array())); var_dump(iterator_to_array($cursor)); printf("Changed %d out of expected 1, (_id=2)\n", $result->getModifiedCount()); $bulk = new MongoDB\Driver\BulkWrite; $bulk->update( array('x' => 2), array('$set' => array('x' => 41)), array('multi' => false, 'upsert' => false) ); $result = $manager->executeBulkWrite(NS, $bulk); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query(array())); var_dump(iterator_to_array($cursor)); printf("Changed %d out of expected 1 (id_=3)\n", $result->getModifiedCount()); $bulk = new MongoDB\Driver\BulkWrite; $bulk->update( array('x' => 2), array('$set' => array('x' => 42)), array('multi' => true, 'upsert' => false) ); $result = $manager->executeBulkWrite(NS, $bulk); $cursor = $manager->executeQuery(NS, new MongoDB\Driver\Query(array())); var_dump(iterator_to_array($cursor)); printf("Changed %d out of expected 3 (_id=4, _id=5, _id=6)\n", $result->getModifiedCount()); ?> ===DONE=== --EXPECTF-- Changed 1 out of expected 1 (_id=1) array(6) { [0]=> object(stdClass)#%d (2) { ["_id"]=> int(1) ["x"]=> int(3) } [1]=> object(stdClass)#%d (2) { ["_id"]=> int(2) ["x"]=> int(2) } [2]=> object(stdClass)#%d (2) { ["_id"]=> int(3) ["x"]=> int(2) } [3]=> object(stdClass)#%d (2) { ["_id"]=> int(4) ["x"]=> int(2) } [4]=> object(stdClass)#%d (2) { ["_id"]=> int(5) ["x"]=> int(2) } [5]=> object(stdClass)#%d (2) { ["_id"]=> int(6) ["x"]=> int(2) } } Changed 2 out of expected 2, (_id=5, _id=6) array(6) { [0]=> object(stdClass)#%d (2) { ["_id"]=> int(1) ["x"]=> int(3) } [1]=> object(stdClass)#%d (2) { ["_id"]=> int(2) ["x"]=> int(4) } [2]=> object(stdClass)#%d (2) { ["_id"]=> int(3) ["x"]=> int(2) } [3]=> object(stdClass)#%d (2) { ["_id"]=> int(4) ["x"]=> int(2) } [4]=> object(stdClass)#%d (2) { ["_id"]=> int(5) ["x"]=> int(2) } [5]=> object(stdClass)#%d (2) { ["_id"]=> int(6) ["x"]=> int(2) } } Changed 1 out of expected 1, (_id=2) array(6) { [0]=> object(stdClass)#%d (2) { ["_id"]=> int(1) ["x"]=> int(3) } [1]=> object(stdClass)#%d (2) { ["_id"]=> int(2) ["x"]=> int(4) } [2]=> object(stdClass)#%d (2) { ["_id"]=> int(3) ["x"]=> int(41) } [3]=> object(stdClass)#%d (2) { ["_id"]=> int(4) ["x"]=> int(2) } [4]=> object(stdClass)#%d (2) { ["_id"]=> int(5) ["x"]=> int(2) } [5]=> object(stdClass)#%d (2) { ["_id"]=> int(6) ["x"]=> int(2) } } Changed 1 out of expected 1 (id_=3) array(6) { [0]=> object(stdClass)#%d (2) { ["_id"]=> int(1) ["x"]=> int(3) } [1]=> object(stdClass)#%d (2) { ["_id"]=> int(2) ["x"]=> int(4) } [2]=> object(stdClass)#%d (2) { ["_id"]=> int(3) ["x"]=> int(41) } [3]=> object(stdClass)#%d (2) { ["_id"]=> int(4) ["x"]=> int(42) } [4]=> object(stdClass)#%d (2) { ["_id"]=> int(5) ["x"]=> int(42) } [5]=> object(stdClass)#%d (2) { ["_id"]=> int(6) ["x"]=> int(42) } } Changed 3 out of expected 3 (_id=4, _id=5, _id=6) ===DONE=== mongodb-1.1.5/tests/standalone/write-error-001.phpt0000664000175000017500000000144312673034026021756 0ustar jmikolajmikola--TEST-- MongoDB\Driver\Manager::executeInsert() --SKIPIF-- --FILE-- "Hannes", "country" => "USA", "gender" => "male"); $bulk = new \MongoDB\Driver\BulkWrite(['ordered' => true]); $hannes_id = $bulk->insert($hannes); $w = 2; $wtimeout = 1000; $writeConcern = new \MongoDB\Driver\WriteConcern($w, $wtimeout); throws(function() use($bulk, $writeConcern, $manager) { $result = $manager->executeBulkWrite(NS, $bulk, $writeConcern); }, "MongoDB\Driver\Exception\ConnectionException"); ?> ===DONE=== --EXPECTF-- OK: Got MongoDB\Driver\Exception\ConnectionException ===DONE=== mongodb-1.1.5/tests/standalone/writeresult-isacknowledged-001.phpt0000664000175000017500000000202712673034026025046 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteResult::isAcknowledged() with default WriteConcern --SKIPIF-- --FILE-- insert(array('x' => 1)); $result = $manager->executeBulkWrite(NS, $bulk); printf("WriteResult::isAcknowledged(): %s\n", $result->isAcknowledged() ? 'true' : 'false'); var_dump($result); ?> ===DONE=== --EXPECTF-- WriteResult::isAcknowledged(): true object(MongoDB\Driver\WriteResult)#%d (%d) { ["nInserted"]=> int(1) ["nMatched"]=> int(0) ["nModified"]=> int(0) ["nRemoved"]=> int(0) ["nUpserted"]=> int(0) ["upsertedIds"]=> array(0) { } ["writeErrors"]=> array(0) { } ["writeConcernError"]=> NULL ["writeConcern"]=> array(%d) { ["w"]=> NULL ["wmajority"]=> bool(false) ["wtimeout"]=> int(0) ["journal"]=> NULL } } ===DONE=== mongodb-1.1.5/tests/standalone/writeresult-isacknowledged-002.phpt0000664000175000017500000000216712673034026025054 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteResult::isAcknowledged() with inherited WriteConcern --SKIPIF-- --FILE-- insert(array('x' => 1)); $result = $manager->executeBulkWrite(NS, $bulk); printf("WriteResult::isAcknowledged(): %s\n", $result->isAcknowledged() ? 'true' : 'false'); var_dump($result); ?> ===DONE=== --EXPECTF-- WriteResult::isAcknowledged(): false object(MongoDB\Driver\WriteResult)#%d (%d) { ["nInserted"]=> int(0) ["nMatched"]=> int(0) ["nModified"]=> int(0) ["nRemoved"]=> int(0) ["nUpserted"]=> int(0) ["upsertedIds"]=> array(0) { } ["writeErrors"]=> array(0) { } ["writeConcernError"]=> NULL ["writeConcern"]=> array(%d) { ["w"]=> int(0) ["wmajority"]=> bool(false) ["wtimeout"]=> int(0) ["journal"]=> NULL } } ===DONE=== mongodb-1.1.5/tests/standalone/writeresult-isacknowledged-003.phpt0000664000175000017500000000207512673034026025053 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteResult::isAcknowledged() with custom WriteConcern --SKIPIF-- --FILE-- insert(array('x' => 2)); $result = $manager->executeBulkWrite(NS, $bulk, new MongoDB\Driver\WriteConcern(0)); printf("WriteResult::isAcknowledged(): %s\n", $result->isAcknowledged() ? 'true' : 'false'); var_dump($result); ?> ===DONE=== --EXPECTF-- WriteResult::isAcknowledged(): false object(MongoDB\Driver\WriteResult)#%d (%d) { ["nInserted"]=> int(0) ["nMatched"]=> int(0) ["nModified"]=> int(0) ["nRemoved"]=> int(0) ["nUpserted"]=> int(0) ["upsertedIds"]=> array(0) { } ["writeErrors"]=> array(0) { } ["writeConcernError"]=> NULL ["writeConcern"]=> array(%d) { ["w"]=> int(0) ["wmajority"]=> bool(false) ["wtimeout"]=> int(0) ["journal"]=> NULL } } ===DONE=== mongodb-1.1.5/tests/utils/PHONGO-FIXTURES.json.gz0000664000175000017500000022370112673034026021070 0ustar jmikolajmikola‹ch9UFIXTURES.jsonÄœ[oÛH²Çß÷S4‚Î ñôý²OãØÉ$;ã3Î$Ø]œ‡&Ù”z̋‹my±ßýTS²,y(Z1|ä ° ±%R¬îúÕ¿ªšÿú‚ÿºÆÕ¥-Ü«¿£WñŸUí_½¾?8·Ms]Õi8ø]ü@ðÿ8úõê<úïtʯnõQüAŠöÃ…ûçŸf¶xáó_N¾YU¾éêsýù´œ~yëÞ¤—ÑægºÂú|}¶Ÿç³yTºvsDæë¦ý´º¦÷¶,]³y8·÷GÏì´ìš¦*7$U1·å¢?^•ÓêäÍæÑØWáÈE•µ×¶vèm9õ¥s5ú ŒNjg[—µð©ÑT0%7Ø4­]ÓÀ%þýkýòöM^nÚÚ¹öhù–åõ—6®m×"¾qÖû³û¶ÿ«¹½ª¦]=4¨iá 5¯`\~\¥ýPŠñР¼Jàè_/¼?Ø.æý{Ï+_¶ï^^qÓÅ—pE½![%VÚ ]ÇzЄ’ÈCˆy58èÿòê¶^ùÏëï¶ÈÉ¢t—>ŸÚÖ""ÆŒò[“W£öØ5`ÛXHó¶&2 ÁÆlAp¤”4JÌÇ3[ç®A> ó|̧U™n¹€Ï\Ùb÷mk\|eˆúå¥ B"®5¡rtqàˆH.ÁjO3Èß¶G® ´ ß.»òÖíbC ìç’j§™L)§2¶2!Úrn†?cxQJ chÌœ&$Ét–1ø?ȇ$·¾vJýìnl1ÏÝ(&>Ù:ñMµ‹ÇU}í· 1ŸU¥ûÔ±«Ã€•Q?f&FPzƒ)ßôK¯lÞžo/»<&ÎEáÛÙktlë˜b˽é’ËÚ§S7@¡“*¯`º£¢‚‰ÞzÛ ?olßFèÂ¥(ë¦Ùf,Ñv5 ?älÝ:ñÓÒ7/ªÁˆÌÕ®L}ƒ®ª¼›ÃÌ÷1ŒõeâÓ®lQ Þ†¾uÞ"˜õ𾮉Ї98èXuþîMp7g¾uI[¡§¤*÷­ë¯ u±o}í¤$%T` ^ûÙ(ÉUèc5ËáŽ^ÀeµæpƒZ k·ðÞç¹­Ó™½rãÎáÌ÷Ú=ܦ’Ò‰ j ôkpÇŒŒûlM#Ê4•ü`>[aNÑ»ÚùÔ¢‹yíËi3f¢óºK]™¸¢êÚÙ#¼ó‡péq#®ñKÛgB„ޏÔRÓQ™ÊäS}ø÷s…ÞÛ¢§sœwñr!™áù|g¥/>qeëÀõMŸi1j¤œh·¦ïAídXd„ÂjtMHDaBµ­;³QQÍê]Àe'N`šRJãYbcGŽ5àWeƆcÀo[• Ç´¢)æÎXf³AàÚÔF@Évæ<\λՖշ±{â¬mí.잺Yéêìb©'Xó‰"æ©Àý<ó..`êåù ¹ŸkWĹ] ÷‹ËÒ\ Ë] (C8`"`/µÕ·€ÈÚÍ|X™~æy…ÒÀi8PÜ­Ã[¬-=\D„>§BU–ùÄ÷£Ã;}Šà¤s ýú-.`#,唂'ÁêÙXª¤ÁÚ@ç0¡ÆUgYÁm.aYCtâÆÕçQnc[ìឥ‘ÊLWä¥%¨Ž8_1äûÖƒ…¥ƒôÁ<´ÐLB´ãò¹/AøØ[»tÒjjwÖz ëØ:^Ä]=‡é‰‡³ú¤…IŠŽa6±ßÇpŒ)~”|y¸2)Ž RÎëa X©!pÍ3f ]\ÛÒÛkX5謂¸Û‚{ûa1˜s¹³ßEЯ. aüâQÖ~rqm›Ë=ÌF4¼O‡µ¦Q†È8gØ”ƒ>hg Ñ [–QêRX —»`ëI4qL:—IÉS“1Là»hÊS–b™XÎpª*“D%,±ÊÅ2QÌ)NIâAØÂ @Éäν@û¦ÑNuûÆCVIPJDP1ÎØWd¢¸žpM'FIrC¶Eðs¿za^ 2·OÒ#÷ÜÖ}|>€Ü·¹ŸaŠÉð« PÜT”W ;]¡+i‰|”,ì/\„þtaXù­«»™ç‚ø«ùºTÐ@…Ãé¦X†?š9@؆íŸR†ëõ…ß ]Æ`©j.ž/ÍKA'.‡ÛÜ¢ JtѼF@ŸÑ¼– Éשׂ‡à“¤¥˜ jæƒújÀ1SmÔc¹_Ƙ8`‘(†‡µ+:‚o±tÜšŽ‚÷½Í¯ªº©ÊçL4­±~iCQ1Ã4¥ìD±ˆ`¡øáì$¤ÐÙú²A_lo¨åz’j±}ˆtlð+ã±ì’ÅǶ®r¿Ï²ÒÜ6Á˜ ‰ýCšL3i™¬(¬M4‰ SBCP¶¨ímTØ:qîåc1V:Ö²—; V¹Ž³8f4á6N˜5œÄ$îb@¬Î9ìlšIB“8sd±®´QcË Î±Wù]íÓZö÷Î%—ãœÕV˜âì†Aä)Fq»[Ò~tÌÐÉ©k’ÙO›·¾Ú"h k™›]IÚ‡éÜ!uÓå°b NW|ëÆ',Û'“ƒÒ ²9öÂ¥ð½Ï,_$]c 8sÿ Ká®d7tÁ´\ Êù³A—I!!ž.=Ôèwy:æ>¹kt a{UÂ¥ŽóöÌ7MÕmUÊï§Ävè-Ù‹Z'ŒE˜aömYÈ'cAäá2‘Š`tZ];ÔÑ•Èe{ˆ¤w¾çìï30úЄ ¾k1×ú²áSV×òHH‰õhJBD„KI‡Kê3….Úº±„Îýåªú"Ë“÷©}XFwËïYak¸b¶Kt뱇¬Á(jÖÌPïÆzÔD«sL4>mд׵ŸÎÚhjëó‹¸2V a¥…É@¸ó §Vð \EÌR«yÌ…K“Ðõ"g€Y»ÌR•ªØ îþ%Ì’¨Ê§v/ä–s»»,¢ŽUm%“?a%& Ðq£éSsÈ'ÿuTã^£7•›Ë2È´bPΞ­kµKQ Ø—I ²»IÜ0ìN…KI›»¤íë¬ó¦ 2µqKt'í6²Cu+™œú¤µúŸ@ÐÍêî†nAÏ>÷Àæu¾yD×jÃ5£úù’Éé†>‚ñCó®Í'÷á÷{W¾N7®]­L`>³Aí îaŠåh§°UjÃÈᑆÁ½Aï}ÝÎúÜÕåÜö˜m¾†üÉiÈá4ã¦ùìB?^ã?í!WÉ`ºï >ZªÐg¦ä¸&#iÁÈTΰ4èÂvœ~vum·±Â ÿu  \¡3w9óÍÌ׃v¸/ÊÔþ¶ÚªLÊ&j¸ì ã:"ÕGÂU-"CÔÓÃÕï‚jÓ´®‹ÝÎjl’­b`#Él,w[GƆ&*‘©Lã„i–§Df 'ÖÊ” @é®ñ­Kf°íLȽ2ÄǶÐ],=³åXÿcî)›P%åÊÈ'¢ô"™€´XÚëå¦ï« ·a¿ëÙéBtÞ¥ÆÚú(àòÆÕI/cáìÊzµCÎöbô¼®®@‚t¨—t›PÎ%ë#tÔWWúµY`;TÞ5YýÊ7I¬KlÍU ®Ð—WðÁádËóÚ‚ð-[º®Þ4¶@^ŸTu  øŽÃßAæ6«Ã#,6”(*˜~¾Â®&ýîèx“ÅÚ—Œ&˜ûýnÐ|Ö5êÞ½+¼\óÒ5Be"úÐÉ„©ˆk.Øár—Šr…~± ˜“):ñaYèMnoÝã‰å¯‹ ¢ªÁŠáƒ.Çæ¥ëî PDtÔ4 GDƒŸ<\>BsÃÀ2½hBaeŒ³ÇU Þm±OgÄ÷ \&è ýi#J#)‰\ÆëAa" -;H¹öO{[,J'Ù. ™& ¥ˆ5Ë ‹1¥”¥)7*8]"2ëb nš ngðZ¢´Œ‰²bß»&úÓ.ÒªÜKÑþn˦*vbØ·0eò|Åd¢Ÿ`0–ŒÞPEõYüÛeWº+;ùØÍѲ®Ï!Çî{ƒÃö¿Ùœœ®RÉ=S#ôÅÕj¬›o@» uYÔtMâçÀv †’k<ÒäD9L4¦Ÿ…\tºLE ãÜgÙ ‡z0±¶^Óg]=Ÿ-®„Q§Y-èã 4Hþ¤æÃÕ d~é hH´4ƒZÖ£ 5¿|¸nTcŒÙy ¾~•ðe¦w‘迾ݴ ›Ãl³¡÷û¢`EÚAg¾m)e¸bɆc¦ƒæ¥ˆ°‰8Ú< Ázd#¬c ˆ¬í ¢çG+*Gå´k_Lg>$ªv/02I'œÊ—Îüö9]ÊùàL¹Å¡šÓ§šç»è‡\ižGàxýÎ}:VR¡@šZ«0UVK,•Ñ [±J51’ —š”d2ÓI–’H‹3ǸÒ*M i»¸v‹¨If¾é·$Ý¢èÊtgGSȈ,Fù£4æ',ð.Œ"Õ¸\¦JÉ'‚ò‰ÑÌÜÀ²«·étªκu7ñQ M·Ãëµ|íU`ŸªÝn dt6BÊ>ìËU¼¶[2Ðk˜™ç!|OtÔÌÚªDg>ÝD÷{ZüÿŸZG&/¾Ë‘€¤0’Ðñ-3"â/';B›>úèê¼»tè‹·+*>xöx§à†³Ç”{(nÿêêÆ-7hw<¸ù¦",¢ÔÀ÷¯$¢¡¤q8cQ¦újóØú½²éÊVŒ–BûÂÇ?}k5Ô8k›ÌÀ±·ÃòóÁ²¢éN$Ö/ DÂtDWãš~"D$`^ãƒÑ‘ºù|' •‹Á€@™gv,qBZ ƒƒ0GÉ4s w6U‚†^)IiŒc@lÊÓ4¡ÃYÛËEîÁ{AÞ­¹EÀ·¡¼½a —<‚(9â’ªQú4uó™Í_ÃÜt¡º§ÝjçÁëŽRPt ëúäi_®tyÈÞnçh‹ C—¨¾%òîj ¨J}…àbàíËž_P–ð àò\H¹Ú¨:}‹µ0ÝÈ']èBBðÖðkæ“MÉ EIŸ¯H”BDÛÊßÙû^1Xû{à§ ñLûÈõ¾÷Å×Ó]õÑ©

xøC¼1ÚØ¹›¶ƒò •HtŸê]Sׯë-7½À¡«Én·"}ëªÕJ8fTül¨¥‹uþö󬮺éìÚj—rLá]ýxº)H¡Tõåã>!´¨ —Ã|?hp-##Œo‰¾jiŒ>\òVºµ\ØæÛ›nxÃâ}ƒQØ ¾O¹ì½½¶~æjŒ1}é-2„Ë(<îÄŒêÞ‹#rH¼rŒÎ«®ßð%<e:ZdþX%³Ç3?aå¼7¼³ëèA²– *' â_zùL¦eôø>ï‰4‘Q†‹§&¾ ©×} !‚ &Ù…TÆ›HË™“DH‘¦Î¨vFX®…uILyl²„Cì-3l±©L…‰…44£ƒH­sàà^íD_F¶Â¼¯ÒKˆ§}2&O”\ý„1›@0#n¨’[U°ï¡ê/>nªrò±öÍUÿ¥éƳ’nîS¿zÂô®  ,ì!Û“s¾~wiÚ%ýˆÜÇ}æ6 ¸{`R ñÏJÏÞ7û­h{ÙÚC;8×îžçAÉÙ;¹ê¡Ëܰ]b}D¶s0LBö|²UôTxÿ@ž¥H4¾¾X¤ëµÕõ#z¾]U6~Ÿç&Iõò…ŠF‚‘ímYE"ŰP‡Ã(ÕõÉwt {µôÑh¸ýŵïyj’áô¥»N&&bŒP2èM57ôÉ»¿ßBB‰ÿ#îÚšÛ6’î_A}Oq}&jî—GÇvœÄ²“u.[µoÌ@DD^^d)¿~»g^„T*Ò®rÉLI¦OŸîÓ§·%²_ë&¬Ò=‚Ìw<%õhÅ1˜¶>Ò½s7“ ‚èá¯yÎ{ÇH.Ækó轡`Ï•¼? MË(}u‡ãÓ¥ª4Ç_.'$žŸ!]™PÊñŠÀï2POdá ^Ha-ñ•÷Î béÐû!_}Eÿ²å$†ú¾C«ÚC³¤ªZœpK"3-ê‚Ì=äWÏ¥©?”Í.C]Î_gê|m*þ¦ÖÆÊ¾Û!_ÒÓFجD»P@Àz±£Ÿ€(ÐÝÊf÷D¶‘Ó¦iÓØ †‡[äìgIÓ€)×XdaŸLàÜ"yA³@’ý^£¶$û}éÊ›~º\ V‡Ä´W~|~âßòçæúH-ø¥œ›—ôÒ4r¸< MF«R‚ç³þ3úí]µMSœOD•즟¢rÂÅïðÔ ÷D·÷ëϰ¼mßÂDZY‹h 9Ø;ïÍ’h*Håh9^åBP­ž[@|ƽÒ<» !ûy±[ô(Ã×Ý‘B {2ýä–ÓF}•äp“—î™Ì¨b9!F³QlÎsʈ<„èa¾ñ¬ÔäµÂY¯µ×ŽˆPâȨ2Á8%*4uª ®rP•VŠùÊRGU%KˆAÛ*amÖùÍ"ÔÓĵ£ (ËAO¬ï,H̤µòÞZÆù3µ4«×Ù'‡Y;âæ‡¥;x(¦[K&À$žm¶/÷j¶yöeoü‡Wö<Q=”ü&óÂP£>wß8iÒg÷LƒÛk¡Ž0O FZJñr8Ê­b:û!ŒG­`˜Å Ë8@Ñÿ¸fœ×<Ù …;ÍŸ½‡,kܲWD×#z>Ë^8½Æ e&<: à w=¿áfBc©à ÜÞÅ8‚~íòzJC›f/ÝÔÌeŠŒ‹Ä€¡§ÆùÆE5Ùg·ž•‡›ôaïR?ã5Š¡¨g Íìj"¹”—.êZ™Cî`-·É\ Àž…ƒ~ûV/nêf?}A¬*TŘ¢•·¬®öé<&¦k&TÊ Ã¹Sž0õÀIáÀH­ÄÏuçt›ÿ÷8LÑÎtþŒî ,Ǫ»ð³¼Ø §ÏO¹ª 8û°¬oÃPm÷SçF´i|ØÎqöEاÜ@˜zÕ@øe\’ÚnàaGuŠp£.iµ y´*Œ¶IGCïË›tçØð~ç瀮 ½ð2Ä×:œT#¨FAí?õ4‘(·v° zfÏGK¢Ôx£k‹Ô¦Îè”Á1ÙUofˆ2±Ñã„“»á´ïÂS,9¥¼¼êÈÚœ*uHˆþyƒ3Ç ÚÈžPWó×4‡³ò]gJQJ–ÒF ©µ…Õˆ±ÚZo¯XQ*©l! gŠ’{[rCª$ ©hh•œ¶r&…CÑÜr9>çù$úQv”à¹n ]r÷ºÊJN¼þ‘{t§WhŸ°‰Æ¨¥ÝsÚ7ÄÞeW… DòŠî€¾ïybݙ箊þCµO2¥¹K_ )Ù2¸ Šò´úSÒdh‚œ½EÉÓ ¼d;㉜ý¤Ês !Õ¥Û1ÀÞr!äÄ(šV8*hΨ"èö}rÙGmksìn”Rìt÷\ pCg„_Ü…bFðy«é¸£Ÿá¹âDðs’~–½i ÖBÀ ɨ~[’·õë|¾_P| B/^œQ9ƒ(28dz½­Ž*ñÎbœûßU·ÒäY¦´ EFÀµ =3¦òNÊÀeI(nƒ)eE ·>¼.Ë $0ÎÊ"àMl Nã|Žû µ ÒX=–H4»$9“ô¹Ê _Ûo‹™ê må9ýîoÏÈ:ée ±ÛmGËРîÖm5Aˆ@6óìÍmt*Úþ×XÙÝÊ|öH£bYf-×/'–…WTÙUhv…ðñ…N¿µ_çõéi´·ÈxŸ‚„(ïš©amÍYýødn¹'ÖL™ã*K~> ‰6Têävû1<ôŒP ÚÒmo`â×ùi ÉOÞÍ'qwcšï_úáÌÐ j£þö2£sŠæ'g\^Ô2Ü;Jˆ¾I ™ÌÉ:ø›^Å5áXòYýE)c3£†¿þY5?p/$P«q:HÍϤù©Z k”ž|¢´*TeU)”qÜpf=©to«6Z3_ˆRií=ñ¤0Õ€¥´âÜUâ8Þ]cŸo; #f|ïÜÝ¡–õŸöúÃÑ^sˆïÿ¾о’B£î1KƒÎ«jöë²]¹²lPò_8u’v6á¶ù¤Ýgݸeúdgߣe\DšFVRosÝ®]¿&­LŠÓ iÚ+µY¿L´kNb 7¢hüc«ÓŸ7_){1…×’ N|X@Ƶ?‘–Î?ðÕq0Å^äûÍu8ekûÓbQ7m=¡f§ŒÐlÆÕÅ w”™\s&IÁöª'¹¢ÄÈóÕí„b,qþÎ=u”avÈôp–è¥Jw‰÷Œ±‹û%ĺ)Å£b‰%ØsÇ+”Rgï( |»YÞuÎñRŽŠ›ß,õ'’¡YoÊ› –Œs~é[„ {‡¼üÄ`'‡ãfµ= †Þ„P¿Ì— FëcH*K4~/(Î4 Gƒ‘œ•TW–PR8oü\Á²’žÒÝá+ë¤óÙf¶Õ[|«WíÍÃJËC˼GñpÕÑneêo©‘敵r¸¾×êÔ´ÿ'ä;öŠcëÕPýµŠ«ú°¿ù:€¨ïm¢l?É·ËeÛý¹?6’gŸwc'V¸ëä{›ümQÛz4°ýµÍ}\MÖ´»šîn!ËΤ>õÍÎãÅZÆ ©SæåÐVh›Å[ )sÝ Eþº ÃÞ¤û;Z¾´í*Ü…Å8s}žK‘As¨‘ââù6Ž|2ˆÕãZ!ÉÐN圛·µèàÿw{·Çºë^nË娪ë PÔ“å†_CÓ¬wn’ý…0ÆÏ´Õ—Žì¸´’+ÍN¬I“&gJ[uÆ;DR\gçNQ‹_c©7³qÏ’ÿmSº›ÓãE“K¼\+AgDû$õdÑÜH5싽»Ša?Ôˆg·KžÃß¿êæ:/ç&ø,•…!÷*Á*åyYîJSÎ+˜3Œ!~‚ÐÊ #à9ÄóÙ¯]1?vËv±…ã|á÷ UÞ#<Ö:®Ê›18Á÷FXý\÷¢Kç^gWM9ÏO`CK¿¿ìj¶»9”ÔËŒ¦·] x¯¶‹K¼cqÅJô·mª¬wîD¾N$‰ðöµ;?$¤²µïÇGóì Ö“fiÏHþд¡wkH:á}ó…±Z²!ÜZM_š9£Ù;8ÑÙ—z ÊVOR(CxŸäA7Íx EFæâæ9Qµ"”àb¹Å¢=QI~’±1ä/OÌ€ÓÂ9`ƒÒÝUšäè¦k·½ d?»²-êì ·qu’jÍF þðNè­N+ùs´­ƒÇóò%Ià #Ç µÉ•`Ä<÷ = v®câ ?ÁQÀªUUp_XôÇâÀz¥­lUЂê²Ôº \J&dI¬”Pa" ÑžT–ªbÕ êÞ¶sw{¼â“èï'”øü]-&w.ïc XöÊ¢©¼}¶X÷˃kPf„JÝ4ò²hïGEc)Éeª=šÁ‡Q¯»e Û…)·ÇVªE¦¼'×ͳ?·ƒ1è‘Ô[¶q%*Ž“~F@—ö÷Ša$Ê™CvcB]¢¹TT¼œû.IM²7¸âéݲ¾/Q¢æ]øæNŒ¾L§ÀÉØ‹ )EÝ'eã:]A€í uFµ@²´g7ûe‰›–úù$98äº7Õ > ¼Œ¦O&£/îfde®·§¶G SAøù¤dTP–}i‹°H‡±ûM4ßBPY·_ç'îÎt}—fø±8ëYÊ9'dp™Äî"®ràÚJœE£Û\· ßW(Už9W:ã‚)¥«Jb°ÿªœ— €P)¼c>ÖÊ|ëU¼ ð|„Âç_î¦-rªe]Χ¯›ãã.ۿØÕtÝ,Ç ‹´`^NËK¼ZW nzibªZ ÷ÙvÊÞ2üuÓÞÕåiyïÍòç)«Ìc_Z›8áDHùø¬¸´¹—àžä Ü¥eï27>Š<Ù›“™§÷2mÎ ¹’„hî)–saà¯^o‡~¬—ðF¢CFp·c7ècêž\¨óD£jÂÍ pè¬ëuŽóºƒ;÷áÎ3‚à3@ç<ÝÕÈ´¨¦žZ ôÓ.šÂUÌhYHZal!)•÷†±"@¸t^¥«œcŒ–ÀM+6Üu½õ¸Üdf¾]¸ ¼³GYçc7¾.1ãlF Ÿ } }’n*Œ¿ÎNFÚùs;Çaæ!¥ïq“è>neõí×€äiå Ý›Ûì×yöd5./KFq %ÜG»û°\â³Ou³Ye¨!^%ÕSR:ű_Û1Î1›ɬšùbx©‰ÍÞëuöÃÂNZDs´l=áD?™cZª.oHF¥A3:ž –CþÆŸm÷¤Óý­ß†tìxsˉt¥±„éÊ«ŠW¢´¡Þœ—ÆéB‰¢"\«ª°ÀU¬â¡`LzYTÃíœ%R¤¼¾n Ík'¹|þ',Žû©¼Ãjð¡»Ã?*KÖšWðC´q}OÅA3v Aö’Ü+¢É½†¿(ÿ÷Ž~<æmó:û\¯ÿ†73Ù¬|ÜܹŠ èÛ¾””(á>ž{w°Wø¿´Ié—Q$Ëν‚RÒ1ÆâV¯âß<»‚0Ø9¯DGî~b›7ßbPˆÛéïÖÙ½z² Did`×r~$V`Ij_° Å¥êRë¤BOiõ¸! öm~rMµyÑî½’‚\:'°<·ZêA/‹íEØ; ¸«ý,¾À¾}ˆí×GÚáýÈ90K™ ÁŠÙÂÁ9¡¢FeŒ+ œléC{% ü‚¡¬ŠPi?¼¶'~VuÈ—íÜ5“"Ç›ÕѸñ öb¹i¥%}ß׌kî'§bÇw c ·3)©¸§R,>yÔž»ÛÙ÷øfÄŠ7ÛÕÖïßºw~ÀpN¾‡£é’ü*âÿžĦïw›Éßìù5}Ýn)ßÛv{ÌûäÛ]:yÖí“ë&¢÷Óvj ÷­.𻎔¿ªê²[cV_ Nsb•²/çD¡ $oS´3¥ %igY•8Qæ~ÊœD5w7\ºÜ›p¨Dl )X¢3Öž§D÷f"ÿ8Š{ñ$ÈRi á˜8n*´¦E%„ F;ÉKªV ªƒ …)%ÄoKÅt!½§bxu‡Çuäu™/6¡^|Ÿ$-ù NÓÑ…XÿÚÀË´ãoÀ­g˜H÷Ô°Ñ€rœwü†ö~5‹6äý*Ïú?ãùëðûõ.x¤2Û®¤0‰hòìõ~¬Ivp{{=04¡„3V÷ì힘3ò¼(‘\-k’ÎîyOŸzt¾9c 00ÑõÅâƒPŠóì}³¬Ë6éÌxq2Å™¥x³÷–°ƒšú~TøÞÍ—uÑçuvU¯×‹ÔØøwœ†ªUFW…G+¶±G™¢FùT"ø²çK»5¾Ý*d·EƒŽŒt=ÎTFDû†T… ƒWwHð/ðÒ>m+…ìí v£¤±¸Ívñb€ú|PµØ½Šë¥cáÄ&_²ö@¥È>A`ƒ7y‚- v9ޅؼ==ööÉÕÃÕËÇö-Ú˜™ÔæâA¨â¹VÆ£þ-\äĪç[Ï?)‚t…ò&ÿæ–þX1Ìù *YVG0^åy(ÕèëR \¨JÆ*VhÁte}¸ Š^ "Ýp"ኢ]¯ó"¸Í4â€yÇ‚Èõj>žG(Á^Qò?â®®¹m#ÙþÖ}Y»®‰šïGÄ«TìÄk;›ª} "ŠðB¤lù×ßîe¤U¼ÔCÉ‚ŠD÷œî>}ŽŠVàßМu~İè9Ë•˜Ü;ÞË7õö^ÉHƸp7È|†lÑ&”;@õCÔS…„ÚC,bäÏú F Ý#µA2ìQèÏJu W†BØúëúë¹ ³Ó‡‹¶ƒêÊ?çȦ…±r)Ù¸¢ÅyWÆi¦™çü÷—A"€:A?Z`ù§b¼qÛ,@9)-A9ÀÇÑw„ ó¬š@%೚åŠR¸ÆÐÂSçµ$Ü]*RŒ¯×|q÷›zÍÌQáM¨áh˜ì ¤AÀ\€ž3%–B€3{¬q“fÂ4}­ÊMš;By;ÊQx¹Ý³+ïëüvégg~ŽÓ¤uG‰m­ÛŒ B`lÙ ßlûñäûžÓ€ÊD?›Ýœ2’';pðkì@&‰ˆøß6s$†d箞@H‡3özœs [Í4=aRHpqUe׆ŒLI2/O•ØÕðX4èÕ?ã‚^d¨"ÿÔ8`X†œžO%2³V}žTRc?0JYO%ÎJa¥/œ <m fdá­—F S^„Aùá·”. @\;'¹!Âz1šD¢l¶ªÖÅQ“ˆ7«=-Ã}Ûg×Ì'gL¨ç\ë%Õ‚“TÑÇòš^mýuƒÂ.ËwHÀ…ï£`k[bİ•w}Å›½’J¶ø%uR:HN °Ml0|›3áÆIN'Œn©¤í¬.þ¸ë=gõü 1ÕÿïªÕYâñò“ØõxòQ¢ð%|ü…ì®:„1%Ï hnàC«×—ÙåÆè{}@O!f©†Ê_»€|E¥YÉ‚aªpšÒZ0¥¥ÌKj%ã¥Ì­%¬,òÒÊ=šù.ˆ×í^Aæð„< |ÜÂã¸ï곯ë¼~À|ËVñ%¥ri§ßûÛdžò›í«-ë/­ÏPë: é_oá©ï\ó†=ƒ~pè·«/®ó¨í6þ½sÏ[¡4GUìÔ°béåsKdÊ´{Pä9ݰ JI‡ã(E‚‰Úº§;Ó%å@Æ4Í„ÜXTM-À´þrpñá%<×Ç´ ‰ O­hA”iÀÔ£RýUK¡2 §Î£W‰* \¹U¸Ï®›ûÛÍô¾”£b!°U¤Ìs͵÷¹bPfñ „D…Zçï'z)´kÝâ1.¸dÛ_º¦_{®¿Ž‡}"ùn7 f” A†õ&Í 6;a¬Òqx8 Þ¡:”‚žL¨eŠéM”ˆ>,]ZôŸ¯Ü€Ç!ƒcÏl ¥ìSŸÙ(郔u6¿§hHF …Zã,Â?_¶M1Iù ·v²Ì™ eO7𳄰Å;lÏB3.ß³ë¯Â]hV÷‡}íëõæ8jø…ä’YõÔ]{i3‰l¸Ùxˆ.ˆ´ç‘3¸‡7*ƒ3e*à |öÎIi(‡Yf gÂ*¨¾EArŒæ :ü‹?ø. # Ÿ»ñ#½þ€W—Ýá¡tœPf-LÅý…»šu#ÆRT18ÀÑ™ú·»©^¤Ù[Œ÷—«MX Íž–kò­ìH\ ì´ÖçöÏÝNr¤ïßïúæ‡Ç=T7‰ `s ;Ȳ–ô„„L,vê[Ië²ÕWÙIvm›Ê‡clypHwÏÀ¤÷öC%%Ñ@iôÐÕ×ê#†Y¾Œùä1¯3Tþ³b× "âI¥ G="Ê¥Nf7Ô9SòœqVÂË7ZF·”*§cÁ´¦67%ÖEŽh+”ïL¼ÛíwÔyPú¨Þú_ðrÃ$Õö·úê¡òƒ¢œ“gæ9*<)Àpü±d¼÷®Áq±YöLý‘Ç*;6űÀÆã7rá±Ï^­Vý¼¸€Ó°Z4ƒR;nøÞ×Ý·É‘…õDR~ åCõ¥ÚôÛ|}˾é&¯«Û¶þEÄWÄ:å¾?E^Ý üÎé¸o¡F_³±ó8/'8qG·eϺ¸£2Mä< l¦àz´œòOåÐ ùÆ»æáªëpa×F×§¤`%sܪÂ)ŠÒ›œÚ—P«È…)sK…ÅI/h@¦®—&»qͽ»Éò:\Ýœ€˜û2ˆD¡…OFÄ£·u?U75Ò/ÿ©BŽêÿ³]¹m9’Þôš=n 0ø e×MáZ¢n¤½ÄÍœí&ÏÖõº+ß㟴Ú>í"KíºNÖ>ö:1£/­óî\å"¯…{Zß\q (7†œNÏ÷¿íâ×Â->T×mY Æ›æ]jxªÐv'‡ gf5ê<©*2º Ô_# Ô Öšó Þ˜BþçIçdBÐ…Ê ÆÜ¸àà¸×Y_Bôç,¸²€¯=À8tµb†p'D^²BèÜøäÖÏÝ4aL¼¤¢qdR˜Ìo<÷sm=!És¨\–Ú ùM r@Ë{®Îm¼‹OWníàŸ˜^AN­WHëßöpcKãó6NÍ"I‹ÿ}Ú|KK©`ÝŽì Ìk¤ö+†å; ²nÖçÀ"æš–´‹ßÇ|ó©ÿ±ëÇ Œ˜ïüNä€O¨ÿM¢Hy—·kÝ\²¸€7³óÁÅž—Mõ½>ªPX, 3O-*M%Vr>ËÍW,ÓSöYl×Ý$s·W“¤;ÏK‹ª„Ú;O­wZU2EÐí}\°’ª  àp¦(-a.¤¥€k¸›ØÛ dÝÕ_£Ü…û›ízzpáîüz1µj©,[ ®KÑéüÄßmŠ‘”ð¯N²ç¶õ‰uÖðibUÛÿ¿)|{ä¯M½`Ç #ãÅ- á > aÇ1îú´ …O±ºXGÛØ¶ÿô’·s¬[x4¹RútíÎ4J*EÑÜ#þ‚:ë® _ÿ* Ü}êÈ'$ƒ³ÔR ƒô`)=Ï2Ê·5Yãî×õdí =“Œ.õý‚-‚Ž+?8j;µÑÛ•>íÖ·>X½lõõ]‚håH÷^öR¢‰èS´#¿ŽÝ)3àôN’Xᦦ’§›û)¡xdé~¿† ½ë …mÎÅÿLJkwupúw¼K£bÜÃø¬$ûLZnG—û‹ÐK2«ÅYF¾xùU5½Æ«µâ$°Òj«$ÑRyáJICp9@Òº2·Ž—PûX[Š\h^æ4ÀÑJIYr¯F£þ¿ßÃÍʧîõ*¬×ÓyïÝåeUÏ>*SLe@Ä7ÈHt~h0ù/·%”2PÜ¿HT±2ø¼m|½ÙŒñzPÏw¨æÕw÷ºó¼Óèؼ›‡is·ãØc+12xS› ¿¦“ÎÞàÀlÃç …Ÿ®%H4ådñª ×H¼kà·hj×y­©Q¡ÜÝxп^m›påîÂ|”ÿî\qŒ]7ô©AýÏv›EõhØÔì,‡{}UT·9dýÜ0®u©Yª´˜`´)HàœˆRà< ¦Ðw¹Ï!¸J)ÅáDý=HeŽÂóoê›°®ü$ž?¬ ü¿Ü>cÏ¡üÐ]È;ã¿pëÄåù¸z4 áøNLœÝ–>ò½ËÀm¿3Û÷çºZ¿¨Úfà¾øoú³$ñ‰Ã„vʘ¡Š`Z­¿ÛÝ[ -E¨¿?Æëv0øÃ!u‹ªx#"©oCÓÜ·Ý¿Q£Ž]Ô×WÍ1Œ€¿îQdúòpÔKn©Z ÞšØCÍ>éQ+Áþ*¦3*„&g1Á]á.RàW!LîàP¼aÎXzâT\Y')¡¥2¸€Ë•fJk.‚aeaè;Š;*ˆïþtW!ûo à#ù«iÁ\ñ˜cù¾ÔJ/ù¾YÌO¥x¾/_A ? 6壎wo ´+Ò«¶Ç¸D–_ò Ú´ª­ÜFÂíýh?¸¾V?Ê‘‡Ý.~¤ðG"àt´Ï¡5§ãà3c£dïâ½Û/w/  ïÏWð^ÞÖëƒÕûñ†ñBPýÔ,|”þ·‚‰Q|Ñ_¥Zßèó ýý•[{{Ë e J™/•dŠ€˜Â)¬â9ÇÝà¡b'¶(=6ócdœºçnr@z³£jö÷®š6!ºpÍݼ?'Â)b3"ìc;ú~ÙÔëå4=÷s×ÃÑú@k'‡K2ÙâÏ«­¸Í°O2yÞN‡â»-œžÏ›-~OgwŠõN_/5æ=|93 '‹i(2éâw€]ðyàbÍ{Ç‹ÝÚBsؾþÂ}uUuD`#~êÀ–(™ÅŸâ•i¦Ñÿê _Áw|ºÕœƒ œÃ$îJâ¡× Êð¼VèP2©tid<+J -ƒ.‰ 2÷ÄA5o÷ÙÇ»Èn»ðÙ T¦«ûã–fßn‘±7à[=ßKKèž„¥Ø7Mø©uÙâë~‰ƒü±:<é_tGnh—bêÛ†þÒ8L1˜C}›-Þ´‡ù¶3‰2q_. ÚÚ™{ìÛ'Î}œÝÁ±Í}·£ÓŸô -$f~ª!š¹-Y¨e™FvºZ«Å»ß,[|D€Ùxÿ>ÄEۇ˷Í´~ìÆäFðåƒd¾{pÎ÷‚g–ð}úÈWI›q*?ËQ´ 8z[…Éb…@HÐ*v§JˆjæE {Ε”žbD XAEI . ¯¥Ä©~ÉhÉÇíÁBG<  ¿¼¹Ÿ<Î*fJA3CEÆ 5ßyô~|ÒÇ|±H+ù;ëÐQÑ‹ÎnÛåýœpwÜÈézgÉe»“ÑOÛ±ÃC~¯ÛÞ¯ÅÆÚY»;æ~Ó1þBëû•ï7ɇ$SAÞÀ¾æ–¼ÝÎm)†ˆn£ã2âæPœÜ'^bz­iž×y”º9_RB­•‚œ®±O¤"‹×ͶòרÙ|}%¸³'Ú;³ÙäÏM7–"Ò~êvŸÀQžUb¾Ý§UF >†Ž.šð5UVÔk·š”àÍiŽ<åEî%+Hn4‘ììôŒ².§žzÉ=„lNä…+ ç¾°ãeÿú:Ù`§¸ŒŸÞÕÝ®og·ù’e\ˆLIþQeÝùëÎÅqëŽ×{¦Ã]_n°†‹óü¤¼[µö>1dï†æ£­ÏGkã‘Vø{ö¢âü¯uñH·sÅÞæ=Þ}è3w÷±¯8;ÕãðØiCøé¶ù„àŽ¶Í€ºPOô:uþ˜•Þù¥ÂÔa,ñ›[ߺ#$øŒ’,µ~r šÌ}À¿‡ã<ŸÛóu³Î®á¥ŠŸlúx(¡¢´L¨ðÔx€CZp]0o˜w¼äÄû‚0#% åË\\ø-li‹‰Mý¼Í}–7÷Göû>ฯ¦;pX¬f©ÀKÔRPöØÁoûÛϹytÁ` 7”ÛÝqðÐKôMÏש÷ Dë^ŒÇ}oÃÓ•ÍÞáÄwŒô¾©ÿF¤÷v`ø…=ãg Ò.Å…ÔÄ8Êÿ‹X…uÈéÖ !`àM†7¦NuÈì¸À5>¬Ú¾Ý1MjžÜHTÈŒq*é|¾Ð,ã8z?‹ß×ßîÆ¹UæáÁ¬&3†Ã)¡pð€g€r™+¥¹Ç½F™p¥cÁ jgQhBµV$)KmJªËq3Ñëj}‰; 5¤ªpܼ099LeŒW+6×s)ãSì¹&ji‰!ß8j ?v\pén‚„ëA‰ëmÁó¤€;;‹—~^(zêÏïq¢Øšü$î~H^­¼g{«˜j:ÀðÌ]YsÛF¶þ+|›¸®‰ê}y”OœXN2v®]•·ºa2¢H [ʯŸsºæ°¨©JRŽÄ(”„³K0Ä#¹Ù#j`á˜vNŒÔêóí‰Ô“hÔœhÕ'9Q½¾ý³Š#ÂAôÏûÄôäç ¦á#@–q1%ýB:öýâhù#A2DOÉ‹ˆõýåpß×Ãv¶0A:˜Í)qâ OÃNåºÔœ³À©¶„o‹Ašà ‡*t!HÐý“Âç€[çí„ùíjáv›# ëàUm\8ÿŠªLY™)%O ü›¼ñÏ!juÝÏú´ºžèì·a­=Bœj,O6yW©ñã.±é3öÍBø•§pÚà.rÔ¿“3IÎhÊ!A=€õ_ðCõžýð»®ÚÞ/¯ÃHŸïsç0Dh;eF?7è‡j—ÿ~¼Só*•qÂôE˜€ó gÎý†X–ž{Æ4 N¨äš–ÄçV–Z–Š(b‹¢0¤¤~IÐØÂ˜0u<úwµ:ÿ±2ž:ÿÛ¡@~¿[¢Ð¾_m·ó±•"1袽’!ú{*5øGWÌ\:š¶¼vßLw»ÊÚ/ªâV•9-ÿ_ïZ7¾¬¾½ë«H}É4 9~ÐÁãq'ƒz™}û VöFosLºGsèÖµ:[¼E'WqtŸÜ¬úw ßðÆ÷{ñŠØwOk¶$LO©|v•.›¥é]ME¡¬+c/²äûŠà_;?x*P¤ðŽå%Ës¡œ×LFÚ¢ÔNÍC°0òë`rZhî”ÌK¨ò–—ÓÚû~LÏu]–ÿ‡Ç£ÊõÃÐÛ…9ªãÝßvëT‘ŒÙ©µÜ<(}2º/¸exœ¾Z­oú¯bŒËúˆigæUMÂÿؙȑp»©vûõdîò/nüöÛ€ÐqsÀëmǨ'ÊtUbýó+}.¥Š³óQó¸ÌNzs·™¼™w£û÷PÃvè¹wÅ{<+JÌsåSJ(¢Ä™ååpÞ5að=º Œ‚rÐZk^!@4ÒÍ ÒÎxx{¶p\•†ÚÂ"ÐC@W¦`ž™àµ. ž,ô€Æ2¸E¶¨-VŽç‚_#”ÄÁ‘ÜAxºÑU¾PÂa0‚^êÔ«àÛU¸¿9ù32 m7n#{B=éà7÷ÿ´«¼3[Ô›;hÄ»A‹MúÇŽ@OZêu…âžH:•†v›©3Óð›ÔVòóo¦Õäm$þܬ\y°vÿˆ(%H’Hnë$Òwl£ŽªqjJºîÏû傎NWÂp1.¶©e†rqpþ½+VÅÌeðè-·Ã»7fx‘Ãìå<“FÇqƒ !ÂTx¨öBc5db¸+µ2^Ó\@Z šñ~ÓÝ-<òwX¥Ž³Ü}Ö(01hv‘x^#AŽHmfìTÓ“ùùŸæèÍåvnIý¶&Ú5|9èΣŽ^6ù5-Åâ?;š±Ž·šô§ª{i~l‡F©ÔÔž¯,C>˜ü¶Û„Ñ aô¬X-®ÍŽFÖ+­íÿ€ñ¥ÈÐhyËy¦4.±›û°,Â:ó‘-?XšyÉPÞÚ óÚGö¬²ÜðFó’),Õ‚Ð’–0YV)&s/lîú‡ìb±ú2ßP~T¸Â˜5›»nP£Ç5#ùÔ 1ÕŒ±AÈ©¢¹R§ÀþPS\+¹zìëY»eVר^ãq½ÞË&5€7žÂ÷Ò¹¾æÒPÊÓ6Åù`vTQ5ùÝíŠp;ùìð¡H{o*Æ}îï ·º»A Ìv>_‡·ƒ§I=÷¾ÛèŒp˜ž\« †R¢/ÒVßÎÐfy(r uyî© \”N£ìUz›¹f”>ð¼ð,w¼`BCðz%‚v®`$PÕ_jÃÚß¹e¶Z§vû'düÁ›øõb> ªý?¡/¢büÔùÓjQ–c|¸ßÃzsÇ{ ÊPÙÊU;êÒ0×Î0×j”»ˆ>ôõiz[ëJ +õâ‰Ñ†ýuJ{Å›¹ïÞÆÁŒjs–Mj=ý´™ÃÂ^)l5·°=Êìò- [~>•‚ã¶ïËÜMþ˜E ÜW×{×îøY|p‹ÅühÝã85T‰ÿÒNlf`r•£¥}ªMF`„½ vžö5º§…l³ »|DR“”Ðp;Ï©£yYäL•¥/¡ý6%V÷@½"P`³Ì!¥pé ü;gK- ÛoYƒ™8¹–þ¸Qíb3Êo·U̼͒€iaj¬5ZèŽÑ÷¤ŠWj]nÆñs,‡;³z%ÞøW"£ 7eû4ÅûðûNžA¦L„ÙÝT«ò}ɯÅöjo"àìÐ(È>[ˆ+e™¼›/JxL&oæ1Â+:wLZ”P%4;…ñZ0'ƒ‚ qD %ŠXhá„-Õð§~V\‰e9[»ÝQS÷ŸPv]÷¾Ô¸_Œ+]C“˜1Ë3Ëõ©ÕøÍ|%sûròÛ:ÉWÆÍxOüþ ꢗû.ÆhÍ=O®Q›yŸõ€ÝÞ%š Þ©j°i[Œ®M¨k<‰Úîš)¡ÝÄ/˜>^ÉeÄS\åƒÆdmÔ]eøù€kV³J 8½«T@doÏ\§‚+Ô£ó‡ù±ÇƒU!=Uϯu=$ƒvI÷Jçí_%¡€k(‹Éð¨Ìp¢^„í X¥õŽÃð^(maœwÊ‹B›¢ä\‡@‹ÜÊBÁ„‡Rñ`œ3–[šÓ~î”ëþ»²Â•® ¨îg»A¸j<ÏŒä­0ÉŠLRf §f…·«¿ÃãØ8ÿ¯Ý &ãX»‘mRÆ&‰:Ù«%]úDëpåñaÎÏ&íN?9l÷NO±¸&q©Èn2I7¦½~‰of%ª¿œÁ¢‰Q“ŠÐ3ùçÂ{@âÍëŸî‰vë‹ÿWs3Ì¡·+¶ï¤|QxÉ·ßë.ѼH2T†ü"Zˆ=0ƒ”h¬=õ…Õª4áÎJ¯ÓÔ"s¯e‘—Ž]2“Û¼Ð^:cK“û@r˜´ûWâ_!ƒ»µÏ¶³yXÕV¿u‹0¸UK‚Ž£qN9™R¥§Ôrú@:ÌÛïŠõ⦚ ^Vl‘ó»åmOÈ_å•{ V\Tcnjr[¦©¥öŠêmm¶w┹tss;l¯çËzi;ôJÔ=Îä{`KÕËcäŽaY©Ñ¸æ8[¼+®íäÝãz;Gw‡®ßþ=´;íŸà+6k{…ß°óG,Î¥´ ùÏnì ¡šÃt<æSÍ3©RÙ‘¡y‹ËþrňȓcŽ@‹Ç•d” å1Þ*K ¶3¦½-˜3¥àò—^á$dÍi`hÿØíwñœ² Š'鑿ƒ5ý·¼qk7ìFÒ©‚€×Ô’ªÉ©ª ïVÑÒqú­gL-Ú‰!¸ß -Z§QßY„]µìÛPÈþ¸uiçíoâ)¢1î!ÎßU½‰k´„~mmԲɯa¼á©¥Œµ] VÓè=jç$-Ñò|ªšk6yù ~@•ycuLc½æJN`>@íÜÅñ¯ûû#NãÔHöÜ9Aë Ê&Ï 7Pÿ"•ÿñ~.ù¥ZÙÇ—I2Ç»§'9üXY0Äd°·uKÊ.mlLsì®<k#ˆ›ýŽ<2Ò’?d}C+v•,$Â^–˜&>„æN–D&[p™ÖÀÿ°N5Ľfºá{­c¢ÜH¶°FPbéùª…}Þ…¿G2ÆZ«èýÈ P=@ƒs*%æzõy¾™³—“¹]_5YãG×{d«SB`Òš½#³wllÈ+c­ý¹¤3“l¤ëû}•LÂS7©.·®½âöͤ·ŠB“>™ÞOäì`ÃÓ¨L¤!„êŒxyÉ S“«Ü#70ÎUNöÓÖÚ ÅhAݬܘ5¾ª®”PÏž/„È8J?Žžã)ÍŒ„†ý"÷ºÊE~9øaîÓ+uAK­ÉóÒP ó°¦zwÈhN¡lœ¡£T¡ È(Ü1+•ôª4:ôs^$©õ*ë"ÿ Úï»áîâý úì]8~ T½€ùhÊsÇÌ©ØùOó¿Ý¼Î{·í?ÆÇ#ݼ+úèÚT–†¼ÐÖ5ãÍ/UøE-!xÅ6Ôœvü{éwi¸Ú†×C©‚zuFÍW(FO®¡ ¸u“·hoÑ{â'èâaà0 öènuž;º)™ÐÜŒ³Þ$Ï(ºÄ]„»ùúøÄÂ¥³BP–i–’‡œR ԓ2Ö1å +…–V±À”,‰"…– Æ êSI{ƒ:‡`õu“A451üâ}ìn¸N–ßs$Œ Éü"N ~߆—“h5•¸øÀöæ‚yŒØ'ýy# ¹KQÜnó7Û'jñ Î6âyZÁ®–•‹Ðûçi\!ÚÙ :4– ·óÕWïô®jsšúÙ>gÔk®œ0m•_ƨ9Ñqšiu¾›'B*”©»£ß4<»õ¦ö•—:µƒ÷fîÇ’G·Uyn¨•$Ctk¯îþU4³¸_¸Èmb;C( ”¶Â³Ò±Âiar¯P£†J‚W6ŠËs’{]ZhÀm€´ãÊ’­$E-±'q­»„wwljH¿\Ãæ îçm2±í)eSaäTÁ\ü`:uLx“À4zÊ÷d’Ѷ%UUËNVv°°ûäWäËUÇÅ/‘ºFŒò· Õ‡f.pÕD]§P“¾æè˜Ï4Ð…¸»lí8SÆb ~BFËóí…jr )|Û¿}q‹Îßßâw†‹×›þ®¡8Úl\1ƒGzÛrx²6€ÊgáA Ï=]LÏÚ6õ”Í$ç/r•p ï²»Ýzí}j ÇF!h.´¦Dyå&Vohμх”š¢ ž1)¹*…ÎZSÊ2 Hí³Ûék÷a†á8®Oˆ`ßHîhùyÁ¡Ö =Þ©3ƵCõ§¹‹h„y…à¿ ~Ù{HÆÒéà¸å.Sx²û‹{>ønZh¥xjüs׶ܶµd…u^’Ô„¨}¿<&¶ã“Øš8Ç>Iͼm"LŠÈðbKþúéÞ7ÒkXÔä!–-êRú²ºW¯5^¹¶FÒ êßC¢i<¢ú]÷ÕÓ¾áæ¼½±¯§Ôqƒ Àîo½q«jÖ^@i4 §ƒ W X´yÁ;ûGÖ$p¸¼ ws—­ýöK9ª-M¸H .˜sZÛÔ¤.“”er IIVð‚ãêÐÃûTj¸É]Î,TîÜÁ3ª¨FwåÎe¤ktÀÜ•óDäsÙúŒþÐÛÀ7g æ«*®ÉÒp¶„lÃïO ¾¿‰ZíÂÇ5î^G¨¼ýÁ\DöýN=´%¢öÈø‹tÆô½QŒoêry¸¿ý"ßÝßœÔ–Ûæô¦a wEøîƒÀmkt=U¼%1ª÷Å’ÕR,Þ@ ­«š*Üœã‰A|Üw„*ÝêÑ áM¹Ýúý¬á`”g§™HÍÔôÞ’‹ð´$Wa Gu™ds>‹9ã¥iŠÝyJln”s\ŽFr©ÓœX¨è<ð G„. ð”R‹¶0ZøŒ/³¶ÂNòyÚÓî!õ§ò“ð§?ÞMdŽZV'VZyÏåS›xL߆~ÍßÁÞºS¥Å›œê=\?kÿÈ`3-¨kš?öøqÑßêå!8¶Kþ €À8:h#ºQ@óV~h~9ü.(etñê“ÛÞ…ÅÛòv5I,|sü„ ²Ç#ÿBüòg¹»-·³(Äœ Ó–® ÝM$—ŠNBw­B×înSmO¥/N">ˬ, Û,|j 4èDÁ·”a -cN•%"O)³ÎB±/ jP^X'Aý[7"9ÿÝ›g!÷—ÿÇ'€_+¾Ÿá;SÏ“·zo«Ï~ùûnÈiúö€Iƒñ'Jc56/¾qŒ¨…³bð×®oýÐÉÛ¾:a…jÞ øra'7êþ ÒÃaAÜ"@¬£´u—ŽÑܾ›6N@•@Ž‹%)ÕâÕ¦üèV‹÷ïFT©OÆ/Ý~ßsÔ0瓌•ÁffPãšÙ€‰„ ˆ§éd`ÎŒåWÙù?§ía\p‹ZïŒWN(‰<æˆË `\Á2n8$”f*ÏŒ¡:Ë än2‘CùÃHàcµübFç)ìÀ“³K7ð LÚG!OIh´Èø¿cö7ðׯx8!~¯‹}½è†j§eâ>€öî   ­­D÷ÎÎD®ËB>Îùâ„°"ï­'£ãt¼èí8‰½vb ]©ºaÀZ#Êl6‹wî°ª±>·mçû›ƒûTúÏ“ya®¿´ÕÚ­¶rT7Ó(Ŧž1øfÐ>B3PœMùœX+…gÂÛ ¾Åœ+4Ï4²pÚ3Űnfæ7Ñš$Iñ ~.x yp°í*¿šBßsnT€WfO ¼üî§;ˆÃåëj32Ä‹’Á:*(S÷Ó@Øû«)äøæÿp@ÚŒ·…Í;Švx¶.ÒËÖ¢2ž!@¢)üî‰l®%êuèËöCóht[ÈÚÍX`*àêzôÜè‡ù–™ÿs|‹4ú1Oy•Xtí½isë.B³ž  ñL> ª?Þsß³\Sg!/@rÈ3ç(g™-$ÉD–Aíà9-¸HmFO ]üï|êrP=ÏrnS=Œ ç¾Þø2[ÅâWSA-äRrêi-ž|/$ÿ@òµÕî…:!®öSÁo~—û¯«ô¼Úa)¹R̃é”Õá¶ÎY(:ù”A¥V9¹„3®¼bŒyFDZÐ"ç¹pÝT¬Ç« ’îý°lÀºÜ¡ççr¥ž^?+ö_ïü¸”ÈOÛõ:áI9NIé’ ƒ´âÕež,È]„éØ_Ý7Ò¸qWïùÂÿ¡‡Q;òô:Sœ>®Æ÷t|¾¬“íDŽž’u°ÇOzŒ(?Ä O ô¢á]½%8!Oÿ „T—ëÕ2Ø—à¼(Tú†â3lhqBÑý>UîíýZ}žÑ¯35L­¹*Ň¡þ¾-¶/"‰ Ò^Gà~DÉ»…„;øˆ¿3K-Òjnáé°ÔÇÐàÎÉB잦Rz<ôµÐ¤H&Íã’ªázÿ±Ú"2ßJ; ˜ÿ{WúÑõÞ;·[OŽòP(DI¹D Ú{c ì?µÚÃ#½™ôÂjhµ‡ºè©/dî¹(ãwΕ/ˆ3{nxñU§ßþº. l‹'…vQ@Ü\n/¬!‹·Ç´ú\¾ Üþâb7Þrýûüw’Ñ£*ÚóâW;ìžw]¨­¡rK­&×óKèé ž:\e‡¸¥“ýç²mÛ©J­†n7GöAgÛ4˨ϡñKS͵w"3"“6'i&¸.Ò4ƒšrÿEfÈ0KïsºsÇyz?/ OÝŒ[Q¿p»ÃçÝ 쫺míR»$Z`Ó.åS5òßGFÃâí!ãqõv‚\WŸræf§§55‹'gÍ ^\Ûù»Zû~¼n;éøÆi~0Ãêø¸Ñù¶ííÛ7°ˆc“ZŸšPrA‚.Q¹úÇ¿ÿöÐÇiãã£õ.fï+4!Ÿ»ÕVŽQöÙê"ᦕ{¸M$TFr•[}Tîy8ñÒ>UÖfD¾˜…²lð©w©eÛ¹á<çÂP0¾ùÞ)*þQn=ÏÇz…ëèl¬é¬xÿ«ÜL|½ö»UµÉ'bå=ã½>ΟZ°wîcV®\¼<þ| uzpÈ€w£¡¤wºCÚÞin?â÷ÍäA‹é¶Ýî÷ð(ÉÑ‘mcôFfNÿ¨®™â{׿Íõá¥U<×i†úá/=@§ñF€€9Œ_޵K…â%wüâ€g-YŸòéc;üD›Í,<ÿ+ZWåŒ=¡úù-mM Ǽ;Ù M¿¾c¿ÜW_ÖÐLïgrX},Ï‘“Ÿæ,³Båiæ…-ˆƒ7iÆòÔBgM=cŽ[¼ãñŠSš 7yÂH=&Oþ¾òaž¤×O‰|GÉ)bŽdâh–BYy-ïSÆ)ÿÐÒ—w~òë¢ð»Ã—ìðŸA„¿ç<±z÷ú=e¯é8±÷÷5£.Šô‡1`ÿ67\èE¹ïèÅÑðõ±Â¤&äsI¹\ïùC“x_»³\}NèEêÈ·“ `x¨è¥T=NÝ¿)¡ ºu³ÆöB·‘Ò‰ÑÄÈISú¥á ü„¼Já…FySûƒ?žAÞ›JS"¬‡P€ÐsDÜÐuK ÕÚ,¨ ‚Ö;ƒ">P¢SášRZäÆH¯†ýìvU pŸ­\îçÍá>”‡q#ê·n]n'âõ?´ýžü?XH-ŒËéhýäC´@š°{2¸Ù¿¦Ùm‚.%zzGg íçJ‹«ÜÐÞútnÉÆÅ„Ô~nѪ)4Nm-ªëKê¸NŸ¤òl,÷8ô*”Î º;Úä,#N Sáï¼»…/]}·ö¾˜G°Ac®t,'ü¼;ú©Á ™”4P‚Þ›óªÿ ! lŽ í–QååmöýÙãádºöêМã×,™‡¾¸k8ÑØ¾Ì×z»íyK3ˆ¼‘`;奡µæT^hµˆ'ïW•Û4ãw2ìJžýP壹¾àå~=´£›ZžIœuÏÊuu´‰Lòˆ#—L(Uê:ç.Ñ`3´yØŒâvë%Þ‡ú—$76OU–R• æSâ\æ‰ç©+‚…F.ŠTä|*3šfJ[Ö£ò%á³ëÖ¶ÌFÇïµÜÊ ü{ùƒ‘’)¡É“ݸ^ºOåþÇÅ_%¶+å¾V»{ï(å¥ß Íê¾™¿uaÿuc_ËáwÇ/-:À¹}#} õP‡·ù”qW_Ãüޤ¹§óUÐ^^®¨HX¼?ø¿W>çêQ“ú¶A!ãÆïQÀ“O]¤†óçæÍRÂfrLg¹‚C¯ïùê˜ïÇÅ1£è“+Œ-hNÒ´(\nRg3hðMJsž+”Aƒßµ,Df¸að /]31?¼Œ?ì‹yG.î“ß¶½*³ÞÊMïâ%[JÁ—†{O…~ò­Ëcº?"Á½^™•ýPÇêYñïݵ ¾°Y³×÷«‡–û²àÕ4¼Öóæ®ÄèSy¦0;þF„½;^ ‚fXkH1=R,dÒ©Ø~½©à7ùèÍ‹j7+´¥‚-Ïݳ/-M¬âdÐô§}•M”2–\å†-Å‹ÏäP¥ã’µß¥óÜæE&¼Ê|¦ ¥tÎra”Ñðv;QÞz§R¨ì9)¸. ËG_m?<Ò» êäyR·ëyW«wwgwc'ĺ#¼zÜiwMKm,<Tßsùˆ0|tùKFè’+#ïõŸ€­©,·½­ö«Ñ€‡ö¼aÀÔ‡+û“û6œ¸õÛ¯Qš¦-èaKÞÑuÂ\kqætøá«2k½²‚2F‰ßÓͪÕõ:¯ yÌ5ç8Aœ‡„qMߘrL™ñJ&¸—3Ò°Â,Þ oø·~W·ŠLbü ²[@3p1@µ¶jiõ³›o£54÷VNÐ1–pkqd}…Ìñ÷ßÇ]>š5,Ërƒ O¥åF^p%…DŸ^jS¡3™JÀ9õŠå>GÅëÔsCsGÓ” £ü õ•¥3å2ó »8–3>ìüñ0I¿Ñ¾á‰>½a:Qà }Ñ×qVX!ç³KÊÉÁ§\¼ÁÞfSãäG»åŸò0›>2ù %¾¶·‡a ì¹l5Ï­* -›N šR2½)Ã+3%˜¾ÎP< ÊŽsTòBAÒ„.S“”¼"ÄCÍyª¹)8×vx˜;*±(Š"•¢È†yið¤ï}eجÈ cañ—È“&S„0´¦ ìdMzBBÙ¹/Ë÷·[Ç„VRZzÁ{kJÙâCµÛù‡ÈÜœŠˆ_07|zT+áÛŒš­R]UFM$jÈ4}5U†_%·;7^' Sæà{Îs@9a)c)€_)0z­¼ðÒd^Hcð~Ã@ʲúOo¤rjxHtwDnþ.µC ¢yõâÔ¶ûÌLqï·©›ÔW¦„% ;ÞÝ31Ö*¾ôÙºú|ÎÐ:;S6Å/çH` 5‹VwÐóeëÅMPñA‘8Q½©¾ÀOò‚øŸ,• ÏͲ`$Ѻ’!8Ú¾ˆÛ$ŒU¯²AùX=dð”öûXİT q!xo ˹E&´[þ(¨qèZ [(*T&-¼–©TQÅSÊüpÄìŽðlm’G¦35E>•cÑòæ¸:sf?+ Ê2 9ŠžšôñT,/CO?&j¨0ürÃH¡ˆX¼À©ñvñ¿ìÁ§å8‘Jð'\øÇC_û_ÕIeì~N§S Kþ—¹+knÛj²…ocU™¨»/^¾8‰íÄc»ÆõÍÛ]EX áÉØô¯Ÿn’²D „¦XÔ<$•²qn÷éåä£_æê²}¤"L«^Ù¯»«¤­´B·ì‹ ®:”’©â±1âa¯19NMäŽQm5g†¸ Q`<!bæÑ}Ø*}|$ÑA;JY4ø¨ûív¾¯Ë0«Rƒ‚—ã,w6qQ–ò¸›<ÀŒÐºVWz!;<\ï=tîÆé¹Ã9£#Æ®…e~¯ˆÏ““—¨ <9ž†¼»‡C©* Ð'ÝéÆOíIéSã„â$¼àz0û˜0Áùe6eæðÅÖÀPUq‘S¬Ì‘,rlËCvŸ Hñ ’¬”œÐ$œÉF{žB´4¢ýS6AûþòÞ×”3§£°ñ·ÞËÃ9/“›¹¡²ý3„Wï)çåáP|‡Ó"qõ|òWЂsÛûÜÁ%åð¯j~œ¯°…³²fòª©·k¹Ÿ×( uëåÖ?^v°dò²qRs|\ÓËu†Ggz·».kíH+m­UƒÉØT ë›–ü"®„EÈóÜ»#N|¿B7¯1aÇå1Lnx¢>i³uvËÐÎx˜éïªË!s¥!#Ó U£µÌ½òõbYÍ]‚Ó|T·ûO (ߊÐ׫Yê2ÞpJÆà…º2’cŒ9hÓÀ)¼i6‹ÅóÉoëÅÍIÚu×.ËGr‹5ôóejš(`ûõªÝ9-ߎ‰X2Ø6Þ‘š×¸n6"So°"DAíé²¥°JÈr»Æp‘ R«‹,x¬Ñ÷¸8â¨dD‹àpì#JM ÌHÀG”2IÍmNÂgŸ å* C’6QšΆ9nû–«”ަø­1ÁÈÎqt]]žàWú ±d¤œÂÉy2$gB³Rúе3lã(À0õL^Á-Q"8¥%—O«¶Y¥îT=ŸlçÛ·yÕµíM¹ÀŒaPϧöù8|ü¬©Ý./».f°_ói«àþºh*MÜR±‹ÌŒC66w¢XwVÌD>'Áéà"GOh¶]K&*“ü)Xg,áRq£ 7*EàÆV¹ ýî_Û­Îr3_ެ=¯fë¢|®f ŒI¦\Ò)á¬4 óHÚK/ü–oa²/  ”ž)aðeò³á„Y1ù«^ý„ض6ð%ÿ¤ß ô)Ÿ;œ¡ÈëscdþpH;UÌ>ù<6VO€ysœ—Á¿Ë¸¡Ð¾a×å`` H •ž-îUÉyšbC|NJ9‘R2¥È!îd+T–[£réxî—Dïn5KÕ?õ"¤ÅÏv‚þL‹Å&—%®6·o @^ixàú„–„Іi±œ¾©ýÑ*ÊÑÞ1~Î9BqEÉ-°z>ùâzk`wŲE:‰–ÇLYJbzex/»‰–„#d$LTŠ¥/\¾cµ »òI±Ä²Ñì|·¼Â…$)R†¢½ä¨îíŒqÄAÔ±°”B².KJµ &}é‡Iû-ñqŠÞ/0S,ô}ÙªlX´^bzÊ(#?0chü纾nÒfÇòÛÅ@#>“öŒ„…Z6ùïuãÖyòÇ¢I½/þ©ÇÉËÍðjÏǼü{é®1Íõä“dÓí’®Ô„ —Å*f\F?·]ÎÖ®šw®¨I‚¶É[…jê(»±&´¨¢ÊZËrähP5ÅcéØ&Î|¢Â» Iê¯"D¦jÂ^ábPÞ­cY5ûwYGÃ#¨0^Iøm)bXqürçS‹ö”]ø ¸M˜ÍëÃõ¢#Áy8‡­¡ç[#\ÓÉ>¤M>À6Èô?98HV`Õøœ¾fõÔ‚6À.+x°ýnô¿®‚4±2ŒÊËXºÍÛEצ[‰bëReÏ„'!Âvo ‰¡î¤W:*ë,$fŽ ä ppã"|–º´ú ë½·Üâ꯮úîVË:Œsrü3¡ˆë¦„›·íBU³¼š+ƒÔwʵr¥Kű·ÝžÝ‡ iVRu>n·d&»q¶Ò ÷ ïá¥ÑÒd)ŒYNŸ:ù¾£`ÔšA¡^¡!Q½È@ÿº íj•*÷ ½9H¾˜‘p /”ËÁ'Ï)H*¨R‘C>c‰Ž[¡YŒ9Jf$âŒç4ìývx»‡»+Î(¿^w×Ã…0®Ÿñ+y¯0Û'ÛŽ?]hýrz¿¹>E¸²LÙ3J"Y+€œì¹ š„ïíûUKnÑò¢Ù„Ó4åQCýBôï&^vI²RŠž’D¢ ÈŒÒâ"YØ Ð“ëª··8£Lm„{žÙÈLQÈgõœäaÏfgᜇ·Æ`»r/'•7.Â&‰‚çØ×ut³ ^—¹oÜfT—å_MÙoìßí‰ È'¦L)d±RÙø-šwM߸Ms4‰v4ØS œž¥0ùÛämÝxnîœúN‘•WÛEŒ“ÂaáóF‘§W!‚[¡CÔ0[™*S)¸æ2ÃbÎ{*•kb*ëŒPƒŒ^JsæÒ¹h‘'›"ŠW8—˜Œ@áqàŸŒÕNXÜ1&FËÒR1zЇª]Ö‹åHcÎÝbÝäbÿ¯:-ÚïCU/Mì•TlŠc£¬üW»ø¸Nð4žï§å÷M|7Ÿ—#ŒÖÌªÏØ`šòfÛ¾¿ó·ÜõX¬oS­ðËöôœÿcB „PöÔ JÜ Ç‰ßÁu|e3…ÝÔ à§Ì(®nÊj\ å9[)œ"!<´æÞ:¯|¬gâ½¥Y8ª<‘ ÞPmÄûû’?±ÙR»ù}í!Ü|îÚ"]yÝp5LØŠpVQy`ªx°¿q«ÕtÌA"ˆRRLÎ!ÑëHzÝXÇÇÈò—ƒº>AVV8•}…%ONWpŸP‘‚†$8cíEB˼n0?>Tm=ØÑRKO².ŠR®„¥ÚÓh“’‘F©° -¡Êz@M:A$Ê®0±¿¿§&Œ,•QñáÈÆ*¬­n} *~Y)‘ø7{¹ûÁÍ0A~÷3Kü䣃7gW¾õEíWO½EÈ.ï 3!U¿{Ÿs/p´ënDÔÀ©«'/+VÁY!z‹ wW SY`Šú" eÓ¸îXý4¸v8lï=¼è”9­Ð'I»¬•¥Î¯‡,GmUŒ5qóEñ*Ò‚ÏZó?»†Å8µŠÙ¦9’i<袤c9ú£½c«Ã¥LëåvWàùäï²Í²ŽM&a‚Âð¨{z¾. Æ÷.Ôiò¾]µÝw·¹uîÏp×.œv?g>*˜èe—„ˆ&×VšÁUc&*-¹ŒœË7à%Ë›S÷½ƒe ÄqÈ•dLŒP ÄY{HÿT–” ¤!7&™É.g×(D>›ÂÄ×¶q^Í÷çÛ¸‰ü™û^”üÍ …l4ò©áb* þZ•F‹ÿ†ÿÃw¸»ØMß9À=0 ¿%—ÔžoŽ…ÎéäU·®ÃÍræ7“wh§ºßd±ý>š‡ó’Ý·™Cõ—ô}3ñ0¾ô© ½¥§ S{l„Až<(ˆ$ Là2ÁšvU­/ç_Vj.C *'³ÃͰäE4ð 5Óp⪬XH\)ÃH0! ¯ 7‹šÀû‘ËügÇå(è¼rÄ£v>íĆªÅR>3WÖ* ¦pE‚²N͈^ Ó†rÎÏèOÏ(Cñü.Ý pî^ÿåvZ’õ.Ýð•—­÷›ÓÝÇÇ:cqóô:úS¦+Eµ:a%X…â"d~—7EÑ$GX,;Ÿ„0‚8\×·<Ç,‰áL’]"D†¤’øÇز§P/d¿±Æ7±ÒYá±ZoÆu _øúÚmÊÛûÜ:¤›Ü(¦¦@ƧŠkúÃ[{+ëé§y}ð>˜n1–ZsFuj% î ¯P¦îB“~  ÚÁ¾NM†wo ƒyL˜¡êðÝ=óKö#Y¥à¸Îи¨¨1ÚÓÿšbk7«fXÿ)†(m’±Ñ:o‰¦<É26à1ÙR\ˆLAz&r–\(ï}JÎsŸªõõ3™°éꆙq«_i“Š4æ÷Ôýl¯ˆ­¨U•óƒ«ÆÛk\Rñ=Ee‘–õÍäÓ·®^ô¶L4`ÞÕ?{CÄcY $;O=Ê2•²R–k2,ϺõbÑ©ymWï«E›æu œ{ŸÉŠG#p?A¢‰6:Ku„‡ªÓÖ^‹yâÂiö´?ŠÌ1‘‚Þ»4jÔ¿ê\}]ÆÞôp»HH¾¥S*ŠäcÛd`÷Û ¯´L{š¿ê°ëSÎÃ,°!£íùÚ)LH3Ù*cN>4˜‚ ¡äï›´B9Õb,3Ožta™˜qÁø°¦ådÔš_d¨89|Ôº¸u"ðîCÀHššÄ%q$*Á9i˽b)2—’¤máj ޾°s²ýú õ ¹á?|T ùw»œ¾JˆÙ)L‘-ŸÉ+e­!œ0YÒ6F×\…WÁFÑÙ0¢ ““/Ûx”Tån•þµƒ£§^žæ(·—éÆÝ=¬Ãù{Í$ZÖë¾sé¼ }qÊHU‚P).3…ƒòCÛò'“ õ¤†˜b KÜ%à(šJçˆ6*CäÉ$Q™”ápêzËp­6ðþó>¶Yߌ³ùBCî"±¸KòPÛÅÒ)Üû”ñ ¥(í‚…Øç“·í?Ï6õ·44Š/8Î)ŸoÕÞ0ÈÊ©›¼jÖ~3¯ºñy„mîh»zå2SjŸÜ'¨|Åq-x°Ébd%%V'/2ÛrÝ$7àŸ˜á0´KÔÑå© ){§©Ï ¢  .sJT^gîN…ê˜ê·­wÍ&@déZÔ¦—ˆýéº.÷U^v©Þïü æ™aêJR>•––Ê`ïÃ;·¾ž5õât|ÓŒpÉÏh1‡ ªU¶ß¸d28¶›b9”¹¹÷“oQÒBSï2„>ùè jPÀûvBÌðÁ"Ò‹Tˆ›¦ÝDUÔ TÓhDˆ$@A«à4Î<9E]L&zƒ²áQÆ`•Ê’Hž³V`¤'©¿Áâ»´2ãŠÃoê˜Úbcå® õVUŠ s-‘“ßÛïiú¾uåh¡9Du ˜gCUzòf½UQBy[Öýònµ8¹Õ¢wu?|Ž6R{ò-z”06ÜR6Hã)V‚µ¼Œ¸‘kïúmÅ$ b‡Ò–@ªªe0ÞN#1*I‚uΤ`£0^J#U„¨¢½…L&Ó@”‹¼_IÏ¡VÝ8-ð?šT–œx·N«Õõ ™ê3Hk¯à ŸªrÈøû?ÞâFÎó d.ó}Üx 3~¤¢gâì|]zBÄäãØUê&Ÿ¾­»Aòþ›ó5¤XgßIÀÛÔ” óÔ¾¤ÀÍeE-7½vnw—) ‘„± ío\¸jî6‡V7‡…/Ê-žAve˜ç‰xA·ÌyK½vW¡ Õ:ˬ) ^ø5]ô„3Èîûy|ß(äPPùjUá¾€Ä×ÏÊ–À´¨]*"’q E­¬™kåÎ\ùr,ç· ö¿•ëaÜ䙂—äBH ㇃bÚÒ ×~Ü!àø~º–Ÿßyýz=äð ],\ ¡: ‰Iñ¤Ç¤ðÂöÌ)>9aðù©N³^qœÏGi£Ž¡Ý‰Æ)GA^`‰"J!XZ™ãR:%¼J± $”Xb(ܸ:#àfI$[jC`2EòñÃnÙüÖ°¥U¯MVVw!ä©Ûh¼{kU§­õWRá¿[9  ‰­Hy†O×)ÿ;#ËrLSZ<`+SÜž=§`ðiWËœ·ü;Œ—ë² ƒåüE#¨ÓÖà§h‘ªwÊØI!çÏOuÂôÂã¡G!.7ÛÕû.Юæ­JÒ ïªhÖnb­"d 3nke^к 8óEh)‹u1³,#ìj×Äká°?WëýÐnýzEûqÇ·oê¬×LÙ+cš‹"©l¿¿çb^0éœÕòáŠ]HÊ\Ý…Ü®ßÏW»@ÕÇ{ç‚¿MžÅ)ee§ÄÓ7ß#s÷L3ÏW„îIE[ÈGa÷¼&˜qlS(/ED–•¬ÁWEI$†š ÕÛ+®ª¤'BR„Ìt0“¦Ô`+ÚV>Ýy›Xú¸Åñ^&6Aµáöæ7k*mæÖ©òNqÞy':pÆ–Ÿ¼ÀO¾º"i¿ºn»Š`ž!d<ä0½•g_¬>û³Ü#ÀzÜ Ç-éÜ<Ð5Št\©¿=9“àíVèIþôù)5Dgù8›$·c7uì²'û¶¬QqReïS¨J¤j˜wIÊòl«ñ9SK¾÷ «L¯ªûä.Á­Âý˹¿ßk üßYù䌅P`o•ÃÙšsÅzäwÏåÖ1ÅÆ…ÝIr.§`l¬þدJ;fŠõÖŠ”¢ÓÁ¥à­öžÉ”j M“,p=}ó8nB¥Ž–±,Ü%¹>æÀöJbjìXϪµyqÆt Iካ–†ä u™õEyB=à²n­€<>‰®¾ÇwŸ½e~r;á^í‰oq"Ôiýä­,€ËŠTg[YŒ"µ<£Etõ#õjo¯e³÷ËKQ -¬á:z4D‘Ig4Ã÷Š-ἪÀkRñu2Üë"¢VÓŽicb¿ú¤o·(µ<ŸÇa? @.ó=-ÙÅx×YfZ…±ãåx÷ËÅa(ïCÓU„´üeеÓîìŪ\“šÒÙËòÅlW£óý“·—O6Få?;Ë/›°/‰àGw–?ùn"Zpo ·÷\×+Û3+ {Öò÷»ñÃìá¢ÙZì˜` |¸Ò8Tå2;’õ)À]È/µF›{SKá!e+ƒ+5 °úhUc#bá—ýe ¹Èe[ñæ%ò¾ÚùU)ÙógÞ±NhÓÊ)oíévv‰ú*н`î!U$åÙOÈh‡²¹Ebó›‰hä›°¡Êñý÷,¯Â°[¢%©h ½3\<ùhŠ¢ý…ÈyÎW¤ìâøãˆà¯ÂÇM9i'8ñ¥K•Œ µç*&É‚eQ—àL²pÍrH,ˤCL ÅzW«O"8& ŸžHÔòµY„¼~ÙnfŠÓŠsÞáàÀ¼’V]ß”îþc³Ù®o·ªÌ7{-Uö!Å»½ðgoÃ~_¶u òÅôã1¯˜ùÕÞÇÛyd¤Íîµ*ÿŒÔ[&õÁï|jÕY5Ùgò¸´…¤í-ÀÍlMŒzŠ…Ò’\Ò*ì`{ÓîÂw5À-”•º¨x­ÖÔ2+—£ÉR'&c`´#Ò¨œ*XŠqQE¯DR›®‡Õ‚÷ÜÃbËôZJn^O¾} ?wÏÂ;%hí!#ÑèæÀ#’ÊQókŽª8 óŠ?àx=òÉ[ÚÌÎ^ŒÛáž;•›Núår~/äû0Y»Ó@,h‹³SO¾á®ó½ãœÛÙ&0ð(УܣГݾ¬¶ý˜ïXOVݯ&ga²ð‘–ëŠ_¥^]¤…w9ùÚ&/Xõ!yQ˜ŽŒ+¦ ÊöâfaÐ2½ÕÎéϵXü¶äñýiÃÖ×`ðΡ…PWZ¶jÄ7.ÖMQ;þ!€ ¸±aîìçÃf}Øý“Fî÷×L~›ñ©PpUX/D‡ØýÔ÷*‚æR`é{´$Aù­eÓv¾iÿypsþ$ šNc‹ä®€qðœŒÆd-´ª¤£=i&x¤pxŸœ‹Æ›G& w,N:M¸ø,¼½ˆ£¼¾ÛC{*½zò¼öª¾“àóR5§S~ Ûröz?'¹Ê<èÙîKõB³³·+ùq8û- €G¼¥õä=¡(/ËpϪáoXü(iÔS³x+z€>;ù³~ª³¬· ÿQ„¿VuöwDONÄV}6Î\!²$YµôÔCL6Áé¤E¶T­,‘o¢¯Ø†ì×ÍZzÅ—JO|¸«íw²¿î€Ã:×Ôò/&¿SÏâ¨t4V׺PÁ¹énöØÏ”‡©BŒPòpt…6Iž½^ï?^ãlŸTºÿù_Žu½ 1ÐxØÞÓÎrã-KGèÎë4ðò“ge€¬˜lØüü˜Ö½UxBU.h†©_…ý~Ýìd‰äXej±2Á‰c) ‹¦8³³ á” F¤‚‘ÁàiN ¦ŒªÕ›i?Ù¯p:È©AsYØO›ãäS6u2 ùECð\ÙØýŒ[ÞáUø+úkyuˆÝq±OÛeŒcÖˆÜÁ”3‰ Ÿ6€²¼9Ýçòϧø´ïq\ 4'–Î@"eºÎKùÔœ¾ó¢7šÝÛPL¤ÞØÇ¸ÿrñÍ›AM¨¬ÅXæB¦R<Ë®æRyMºèP…ÒÁ(-BŒ1„-‹ª$åeMNMÏt­/Ç!,‚üe»nÎÿÒ˜VaÆ)p©y¥“Ì·F +—ïÊæû“ËŒã6á»Ípw´$¥´n‰oðgŸ¿9©™ðÈ€Ö¯:$r7”’ºTµ¯R&F‹9²r))fk‡¬Äs£f²]'©•K~ ã¦Ù*2J¯¿ñ*Ë:DOå¹j¥ìßÇëïÏ^/Îo4;ß¶á㺽X(aW¶ÀÔÃúb½'u†Ëp~(Ûæv äü ¯5©ƒ”•óbtˆN׺]ÀH…åJ«ÂsôI;çs•±d•uiú\»a“ûp[@]t¼it{^ñf«âN’ì;ñ Á^#ÁÃF¿™\pQhœetv©wã¦ä‘Û€ ïn#>Ù.c£5Y™4mYòÚ¦ÊËŠÖÅ“¸ò5U$YRÀk6º2Ò ¬ˆÖÂ2ü4Ãu¿½™^t¾_á3–f$y.׳]Ö†ËÞzÙ{Éý•Ôͦç4ì·]Ó.Ì1¸ªþñžžqí=§-† ÿŸð÷! ^µ îDÎ ”v×UiØUØPtõµ(¤ƒÐD{5*å(¤sQähs£§êï]Z ejiý°ÛQ¿Oöä¡sh†i©$Ž‚nJ2¾:¬h‡Oؾ¿51‘sj2“b÷Ó+¿¬SðÄm®¡fV©ŒUA¼J Z%Uä&û¨€¹MÎá횤K˜Ö©LÚxSŽeÝþkCýÇKåɯۋׇ²Þ|Xßië¾£åËŒíäÔ³ª•)ÿ瀿‡ÄþžßJ·ßžìý ysvó˜$Ùe)ôã¿ûbå_Oßn½Å=K^ hŽTée8ṡˆžxEæd{-¼®Ü8gj,›½ ‰iø¾w$o½.Ž- ß?ŽÛñÎ8Åé.êÝøqnÞœIEúÇ= 7^i«š-é_Îv¥;¸²_ÁCjåMðÇ”2JÅB’Ñ”`¹ô"éœ ¾UŽŒ²¹Ð­¢—ÎX'Ñ$F.XÅô>ÖMA$éoÖ(¯ÙøÏ2ܽ¡ý¶$©”è¶;Æš­4¿ÓÒð0t/ÁÚ6sÄH€È€ê.A}#¾”Mãjk8ºø¤Çñuf8¸¾Ô@–@€%qVr'"3È‹¡€¶fK×®7a°rïÄ»o^Ñôùvžo ©žY+¨õ™]iß ?—á‚ú‚æ/Êð‚€_–ÀéíHÝUã©>ýI+KP¹š”Cäñ§4YE­÷R"Óù" Ó »f_é¢Eh…0*­PUœOŸÛÝŠ˜ÁŽ´_—Õ‘×9´Çøa~®KIÕqÆ;Pv…sך¾½¶6í³+$7–ÅûëT³WÈR€% ÈœLÎÒ|ñÙ^9>jñÖ"5Ö¢4“GTÇ £w`¦¹Êùí*¥þÃÍ^©e-Cáº-ipÜ…tÞ÷^!öz+®„ã-ÇÑ€4¨drÌx/Ë=XQÓ ¹$_^oñÇ’Vû² m)"0ÍÊ'8þn”¢»t¤1|ŽrΣÆk—ÉFø‘×ÊrO¼½•ˆIƒ¯2‚ݲ(on^IÓÐäs4ü;'ø3£dç”l!ç?Ëú¨š5Ûšå€Á=sfi?µB^7as´.qâ%0ÍxxI`F$jI(ÚØh^µG T4Ýxl‡OcÌ4ÌGƒ³°ø¾½‰irfó. Tö;{å$w¼Eÿ‹Úñ¾?{õI^ôFî©PgÚyÛæ†úP [rœu›Çþ2¥Ãfsg€ó”¥Òˆ¨†Î³v ñ ¡–˜HrŽ•ˆÜ3¢q<Ÿ¹´ø-fäÅéùô Þwÿî¸a|tnJ;ÜŠŽÎgÍ:8dÐå®tó–âõqØ÷g7 Â7F_—U»ÃŠüxÀÛ%ÇüöV( çx©}Ì“ Ñ¢€i²#7Ñ¡xIøÍ0Qh¾™s`òB½B³ìŠÍ … ”%MG÷«›ñûEü·ñ:4AÜkdùâR'´ïœƒ¹qº¯Ìéõú‰­ËåEé~úz”õÔÀŠÖy€.,ʅἤ*Þ6®åŠÖµ1k’gHqJG¢¤ÝDq6[UÌÆ×œ’¡…nL#…Ý´qó©Rܬiê”Ë–m.ÛÙ<ø/m¿ÓÏh«rÖéÿ©ÔÂuÙu•ËM˜©Õ‘øµ]F?Ò¸½nÏç#9Ò{Q%°P4P c*bIyW|ŒICb/€¡™'-kñžyqr'mŠ$Fã‚ý-Ì^!þrý©‚Ü)û :Ü3ÆEVÖÓXý•6Íe’Ï·á0tGû9*m ãK¢ñ-MïÿS†¡}¢\eä5Fpª9'LW4Äà`{ÙNš„€ ´ÁjŠT–Q$‘V$‚Åt-#FDáÕ¢Ó{ÛÍÖ<¾t4k_Æ4,â¥nʼ-4Øýµ.wUµ¿‚FM-An#¸øv‹?üy+C³X”­s z¥† H¥ à' VÁÄP ×…jœvÕÓä£ñ,+§ rç‚ÊùnØ-ëøú9l®›v~~;6 ã´xæ•ê<@Ò•e­jÅóñÖ¾Wò‹¤—¹”z‘¹áv׃nòéTŒÅIn@„õ4 §‘¶råC\SÖVZ3%3õCÄ$SPB'—œt«N—™7ácØŽÌ/²îínºßÇí»YGNuø$R Hü€ç22‘R,‰¿«°1M¹º¨UBv<è\™òAs†7ïE0ÀdR$#«—ñO2Zp<¾QªAŒzž.O„¯í2c¾Aò»¼œQÍž¤L_„X€3.;ª#_éö°ás’#šsŸz©;ßNœü“Ü&"I÷Sžr)eÚÀç‚-6F°<gªôÈbŠ3 ñÂà_ö6Åb¿Êezg"bQÙìò‹§16Ë–oÂöïpü¬ gâ^~§@î¯D3©½ š·¬&g¹èê# a½ëSE-Ûz)A)¬qÀlÓoEÃKÊÜÍ”êlͺ¨ª† M fåÀ›´…*ÊÓ¸a=t«(€¼v¹ì „4Ö-ÿîH«}e_iųÿ§ìÚ–ÛÆ‘è¯ø-“*‹… q{Ì¥âìÄIv3©IÕ¾h1"E)Ù–¿~»IÙ–iƾ:Ž,ܺOwŸ>ãÝ•A¡ÅwûÊù~CvÇA SoS7‘ LìJ¥ˆaìYÊvë¿êt¿½´„·/Qò…°Ü@¸¦÷¹…à"geIÀ¯QÇ @¾V du ç¼öÂä`œ—ïrÕÛ¶Î&\&†C¤}ó% 4® âsAù048Ѹóë6¥Š ;Œó¶ïÔngà ˆ¤õ5°eŒ8QU"|ï8ÂåL±u€Ñà'•ƒ@ƒ@ˆWQgJ‡Yd¸ÚU@§ª?”~KiÒEàï•Ӌ¿Ëü-Sb%™NúÀ‰ìÈÂØ{¾¿<µ1³ð®IÛáá [ €¹Äã’(BT:‚:œ–­Bñ8=ˆÚx©sl‹CQø’cDŽ˖,ïn= Ôª‘I÷ö_Ã`ËÈæ¾p1KA(³‚WŽbí.½MuÒÕ¥¯ª&B.æ‚7Aò”Àx³¿‘ÙõÌM?+þs p ®¦-dî+ˆu™±®Àæk]ñÊBA Å%j¯•BºŠ ÷V¯’é€ðá`™5‰38îÛ0öýÒÛßeTZà>k½(Dï º»>âõ­Î…T¨¢›„~ñô²ú¦ëƒ<‹œ)Æ+A•(ò(ËBV•` -¹(´*iîrãdŹ…ý‹|ø²è¶,q[owk_ÃWɺ[Ÿ&ýøq?ì‚Ðâû›ãP„¿…G wÚ„¬Å¥íDZsŸmãGÒ|¿1ëðŽÆ“³×÷ç^•û!»…Õ[´ Ná(e×` ¯4%%–·iú./ˆÊ«³š@ô¯ü–5€QJ´! ‚©i»íëpìü×i#†’‰ÉŒ™äÁÓ§©¥éüì³í‘´ÕùHM4„R¤0¶nü¾Ív‡>Òƒ+Á¡Šœ(%™Ëa¸ëA‹B€Y®,|}¹N ðÞK«àh¹Úµ8¹:iæcïl ;æc;¬TFhžI¦øayJS.P²gñ3Ï“yž°Ë#o:Û,DH§M6àÕ;eqH6.œâÆÃQr/ ñ½>Lá J>ÀoƒõÎY¡©Ä>’åj~=tmÖbóÄ ë8&¾¼è÷zLOtì¨ÇË3Æhބܸìô/ë›r]¿’/6†`2a‡!ÐXçA:7ÕÚè§![¡1²(-쯎!›)ì㬴¸N–zª´Wà •õ*0ÅÒ,Èž‚»´LE3S†˜Ù °(Ql.~,¶½ÍƒffÞj$ÌYX ƒÚÕÑÏE|œÄ‰"… 3,Ò³T„tk àÜ‚•HTU©`×´¦ž'9WV„``µØé`VH¸æàíò4Úß76›^LšpAcûqNZðæ~‹sÌÙTLÿ¡Þ'¯1‡±Ý`&:SíÌ™‚7’‡Ø´³1·ÏØÃŽš¼®ƒÛ [ç 8v2×½õ•—ðg$u9X[ì;•»|®4~ƒeѶYWšˆ]ƒÛ41ð—±–O Ó·9Õ+œ_v'Ãlø¶Þ­ã2ÊäšøM¹µ¯ÌÄ RZã•àWØýÌ‘+i$à®~qÌ87VUp¡i)5ÄvRo(y€ø7¾”Ý}Ö ¯·iÕü?±@Ör²Û9}{^Fʧî] ¸ò‚ŒàLå‡üýØy·™Bº¥œþ,õ“sðè"Åþîz[zl=ÀQ; ÚŒ¶€t©[Åmn¼-iéŒá˜vÈ-3„q̘RزÜÌ ¾Œ#îv½o‹Æ¦±¨~X¸«>He]hg~Ñ”NW°Å+ÀX!Õ—I r5Ö7Âûª ™”}-ßú-\(Ÿ] » !έ4´È ϨÍK*|P 02))DЊҗ²ð`Nd%Ç•„ÑÂTc‚s7l§ÁÖ]†SËS—£ºcÄb¬£¢—¥€õ„Š‘žòu±ã­IÚàP(…ûMç›ë°9-æ—€»ÀxQðY,‡@ŠY« ÌšA@ ‘1`¤P…¼dN&–íEPðÚfv‹¬V€žIÛûw¹‚Ðæ¾ïý&^ÒXaSC‹ALˆžr¼Äç(ÕCxxìöãù°y&8EŠî»ïëU‘Fh×•Ò °ðR0pnp[ —bïáÂ`ˆRÖZPm…rÆU¡),oúÑØe½/|iÓ˜†kQ¾nžª­XNÀù1qŸÇN¥”!_R2ìˆK©ÏíS$¸ÇØ @;ë`£® °H €ºÃŠàþÊJ(; „¸â½² æ˜ uáÞ‚•Úi®Ïû°çÛuÍÒ¬žy­äȵ2’‡²™_íÕUÝESÄ .’: £“oÛ¬´}D+µ=œ<ì bÜWl½è4ðj9+ˆÁ%€6lp.]¨ YÞÜßS;fæÀm}|ƒ VÐÿiË®¨£æBçf^{…¹À;I¨ y¾‘þ¾údcÉK&@«”Û;ÔW˜ƱIã4‰ÐNsp^Œë‚­ŠŠ–8Š9˜QÆŸË-xJxSåÞvY+ÍØð"ØuœØmšCZ¦ø¢÷W]_G&6]Ù˜Ïê8ãð"ƒ¼ x?œŸýi‡M‡£MF9ˆŸë5ÌúsA–ÐÜ싲ß#ç&ÐÐØ À…Ġ̇¥$Ʀ‰Àjt]¬mM…ßQÓý+qÊÆÊÀ—kà%Zâlsê£}h½Ý„#ÎI-)”ö)«o°ápÉ#­ëhš Ds +û-¨&ûp{×h±©„ë¤^‚ÏŒ°aáÝnÖ»|RœÛ£f~<+Ì ï˜t?k0Î.æ£oö%J¦‰p¼k|8-ó½Þ#±æ‘¨s¤>nï#ÜÈ¿ð$ÖºÝ k@[uà›±àºý|ߤ…~êíö>xŒÝ\¸ôÔ"û"˜çƦÓìz¹în-¸ö>³EQÏòŸbiÔó‰ (¼¢Ÿí:tŠS¹tõ¾ßÇ8Q &'&×¹ܩeŸòϰƒ¿U§ù“Û Â¿¨‹¹Æÿ Ž|ðçgSk÷T3x™!ŸÙN£1NJ:¿ ÿ,.qƒÂ!{^`—÷±|ݤ'ûçŠÃ IäWn&àýLŠí¬›cÙ{Ù/Xç·/jšñ²ÅÁ‡ m!«ùµüplÁ>ŸÚ'ˆÄÂH¬Kr¦iC²u¶_^änÓ iÖäÛ¨eï/îÈ‚bË÷&6«‚'€;S2$ÎÖÃ!}ßòÓ›Oíˆ'‰*ëÃÒŸ}ß]–öÙ_½ª„À%19Jz$-¬¿­·ÙzÆ’yêr;нd ªi$=¹¿áÓô½—–ðy¾üÝm]í&ì9å"ÞN‚_ȓҵåÄ»Ê{µ¼Òu×zf—×§\>€œ©W§:ˆepxâ âÿm,—+lG)Kœ8j™mía9?aGºÆ-öÍô©#f>4uÓ÷øk×ûYm? y÷~€þ¶Ûz©Ê)BÈ“4Z¬ºd;;áN¦nEšÀ;6¤íºëH>æ—i™Í™¤(,3)ÁÌžÔÂzÂLZñ¥½ÿ‚ÌòieW§­ò_ad:iF‡ Ì-ŽgÀ9¾ø·WÎpŒ3"Þ"gŠÈ¤ÎýªnÈXHŸãœg€{nSûÛºLãëüDi”`ÛÖE×—÷¸¾@ÀØïU €å7«Kðù‘u2ÎPÄ,IÛhg±ˆåHø¨?|"Ôí·®b8ÄAt³îÇ1âçgï*lÇ$Íœ²0G7àI±¬öú%yòäÒvÈjÍz{Øv‰LÍ!nS?O²M!Œó¨~{~öë!súÒPÍl,§ÔÐ$×~1péU€Æ>vöeEwhSom}ì/mæÕÆ“—:¶Ê¯F.NÄ¡Ì;K…Ùo^j†=^F¸ÅZ‚D˜s(¾‹”}ÂNù ÒU–&hK@©¨F•ò&ר„•¡Jî²ÆÒ?mçÓ ìGøž›0!Óº ‰=r,Î.ún^–Ѐnà&,kgsekÛß<7‚Oϰš(³Ið=&ŽÃ^ÿѦ–7¹—Õ¯G~vørRõ©$fc3öe£ïâ/ºÞ®¥J£tõ‘‚à\rìôìüîþµ¡‰B™§¶~3d#ghqI÷\~_Û5Æ·‰èÆöWA[Ø],êƒ?Ï*ŽO›§–Î)Õ1\ÇÎ’S£¨Ñ)£€ÿ‡M[‡~W/g«°øx[Ý&øø=FØŠâç„bŽo­5cfë“4W&‰uP`U/³3/œ‡`#0šK‹ªª]8cuÑ{¿­|ã‚o=am[ðM«Ð@žy³¹`(†—°Ú[Ô:o,6â-?LìÊpžéMbFç¯È<¡Ï³Ò×É"Z £¥¶\Êœñ4ºñû9üÄÛã“ÀtUs"ä×J sø_êÐÎ2ýãìï(…Õ½ˤØS¿ÞûåªSÑhËZ¿Y§ªý±®£x‹ý\'UDûJë"£ðø´H.±3xqOrŒn‡®MZÜŸ¶m#­†£Xk`a£¨Wcëv$E¬Æõ”¢ý¶Þlºq‚q7,{AÛ` em³Í”FJ„iaˆ¶ )*)t… 9Ì+NÓbEf¤ÔTV·û9Ïîi‰zÌMó“‹G&¬NcC; u¼§‹c£Iž¯©tHcÅç¼üþš±»$ÃM¥÷b®f.´½”=}fYömmd <;@Ñ” ð/Ù¢5ùÍþŸ†ß¯u°ˆÓ/æ§ tÄt F”LRsômÝÌ2~-M+ÙÇËg‹¬ãàË{h†‹ÆF9‘ŒrôæZ€¡hEqG#žt\˜±Û2¸2L_# T=NF{-@USEFA:ŒÝvj¹U·ê;À‰­çáW ùt–to_a-˜$U{¯<|Iùþ¡¿lIÀˆb%%äTpú`TôÉ®}0ƒÖm{œŒ6͉:Öy˜ I*#(§IŠF>ãe{‚M3™Å(*ñ~~;„­Éq¬q¬ŒJ ñ{É$áDšâÐ!B¸_0•Ì—ÑØ&•ÿ3’]Ð-8*}‹¯; b8 Üœ4y’tÏ~<“å;9F"S")]Áè[f#ü½8—ûÔ ªâÐÙ0"~šðØ\kµ¬ÃRŽ€ü_Ÿ:ëÄÚ˜[ ²Œ²+½½?lbJ¨ë"CT“$Žè>3»ZHž?­¶Å¹"IGˆ³êÃUëË—˜öÙt œüV°lÔQ2mŽ0æd lHŠ× œ[v¡·©}ŸXÊþpŒ´ƒ‹ö/§å²ÄùÙÃÏ×Úpe;'‚JT’°îáXÖÉúÑn/ÃÑQ… {øÕ´b çãžÁˆ=R¾ØÜÏURnô‘L’ Ýõº^æÜ4¤“ýϾޖAkûóØXäå‘b7HRjf„IYâf=NÈ\ö{— 5½¤ãû8ò/6¡Õ-ŠW?ãtÑÝH žH㑾+Š.ƨ!’`±4ÿüÓ½@cù,KxÂ(p•ÝÖÂS—d>û¦«‡Ò¤FH°úŒüçíK¢Ñ,ÆÀºšL9Ò«§”^fÛ[ªlüǬeiy5زpUoCUÄ‘…±zEš™s¢•DÆØƒ›Ì*ܹŅå8²k…õ].|ï‚ᢥÝ.dt> E¡_MÝ%›C¥ÁÎ4ÊýQ3‡³Jæ çËmÇñN×]ãÿGÚµ5¹ë¿¢·ó"±x¿<ÚžñNvìרYWòID‹"µ¤¨YͯO7@( öžSµNm%Û@÷×ß…ÉþO µÓ‡×ý¦j+VóÙcÉ]äèð>\$q˜°:âc= ˆ½±Q>¸ª U9]à1{evü´­ð¹lÄŠ‚3Þ#C¯ˆ—¥I–±o­X6»œ  ×Õîå‚qb’Û­xþƒA,²CºÏR.írÔ,BŸÕþ«Ð/l„ë“y&ó«j$F&ð¢í°´!¯SëHæ£8½MÐ÷ü,ÉbÏg‘sEÞ¶§}5ü‰¾/투4絪 ÿå92RÀáÿ±xR-û|†eí;¿Æª+ö½ÔË\žoêÕ`Ú7C9'±††Sô=E¬ k)€ø/±Èç¼XÂ1]XСFÓÐg@e Í›€øåþ Çô®ÊuM~£Ñ‹FM;É“½«Ì’$á1Kt ×1ë{«òBôÔ@VjbU®äqeqW~ªŽGju]c2Ÿ½ˆÓ^·[ߪ×bt€†€ï¡º‹±Ø¥ˆ¹é (yšvmÁ=ž+y<‹|Q·¶ÝÏCFÆ2«Nãç·oú~@nÿžÁÚÀGÄEùFñ ˆvŸ„¡àû`- Ã4e1NXª9›¢ªíloðt†Ó'œ¿ERü.éæø7X=…è|T‚in©—E^˜°æ¿Z KAép<=·I¶¨á@e k§"t_DK6Á— Á¨ï%pµ¤¬$Q¬s—q­lWWÁkÏ^ªÕžuðö"œ¬R´¶˜Ž¼y[9ˆ†¼»P£°Ðõ˜í!O¼ˆ'Ì®¥â+%óH_}{êà"CÙ¾¦`ÂȆœu½*Ym*“Óå3ðþB|0à€-K)ÚÐ|ârÝÔyQ“¢,èþç \¾t“ЭMfº¡ÚX[9èðâšZN‡·­•í}´f>ƒðx4¹ yðõ‡Bþõ¦†½Ôr>2#ñdµÍN„_|ÎI¬ÅY–ÎÛ8š÷F©Ô4!ã3›Éº…Ýøöö–6NÓ勃Wëg8s3FD1EBL2ÞÒ2 5Åžß–÷GU¾´X¬2 =X#üâ<Geºï¼Ž-{µÙAžê¼m†¨™¾F÷SòTL6ú;YèmoÎ-”µ L}7æ ïûã¤ê ¡^âZE³)¼X¹(…À6Ž ¾{9”Š îžë|@m¬‰~3´ÙñÕ+Õ8þKÍw ϧa,jæ¢]Ó1.~•»ûwÄBƒN–Ê Ø8ËSR§Hæ~·jäqKÈÃ+„Å»ÍfÕ¢ÁüÅãÒ*…E‡x7M9HïJ+#¤YÆõá7êtǼúM´xžè Ê:3 ÆP) C7Ë2N­SJQ@Wš¥hËF+àx콪&ÍŸ:%Uˆ=òà,ÆNˆC§ÌXc¼è”ëˆ"'”M¿óÕù{Îô€wüñõ¡oò²0•x÷†ç¡ÙK‚òNgƒ×ʸ¼rÕÙðžFüÍòfE®Ð>Žè‹zì °›¥>öÀŒeŠCÕ$f‘öîþÑ·ò¾šÓð½áîÜw“ËÂa™ŠâVB´q>ÙˆE>‹yµÉóÌ*í-Rýòï-üˆþ äåò8”œöEhÚÂnñy >¨ÜÐ`.fQEN]Ë‘¢¨7²†bé¼Ê†wö>¡å}unƒ!Û¡Ûõ³ØÍf…Bz˜×H?®x£@tƒ'`‚ÙÓë%ÕãÜßÚ&O›‡¶ÐêÇ,ˆ¦„ß jÆYuLQó¥Sì‘e¶Ãå:§ÝÉí®%]Tâ|¦Ò „Žÿ"·ƒÐµ¡VeYÊ„^`kTù俇ñMeö°6ö+‹øÇfÐö¢aˆi BG˸óUæØ#:§qøá°×h¼”Y}Ë‚lý¿k§þ«çÅs[®-µvêzišð¦×•DÔF”ð7€Æßü…æÍ½xÍ#OÝ8,øJBDå ÑÃ(å‘ÖJ¸ÂÌœö£TÄàjǵEü$jK€áü¼§·Ñø|(s "§¬ß˜WšõLËjLýµû™o6–yüGÔ±KûŠ•<Ü*7Mž¾L ˜ñàY ?` yËWÊ÷A GNë·_ª×BÐ8þبòîjQžžóÙ—:àmih‹vË2ƒÀ<–ßܯjFP#9R/´©– "7èÅ;¡{•6ü‹µ59-|nÏȰæòR4Hg%•âU5À8ª¾ÇJÈ›`vÀߥ8Ðfü?%­ÆûÐn ‘Ù‰zaÀ<î‘ð(taœÚ´³ÕQ,Ò½¹ŠS<¯ˆ7šù·W}¡g½“RX­^¼ã5–>1ô1À—sù@ï‰QA+‚7³-ªs7 à-²½o&îVxJÈîW…}ð5F{pî™ü|!÷ù!xaQ]h“@Úòé–qô¹-÷]q6Ö™ ÅO)üã“ÔZ¾•‰ÙÓž“Æ)ª6gªÏÕ¤Àâ6;TJ÷Ÿyôjµ³œÒÐØνyDŠ´ ù¡ ´¿N;øÃfvîƒòi¥×eQÖ£àmban_¤Ëª-k´"+•GçÐZóÖ?ȲªEì³–öÃâ); 7º3Eè\Èàó—+ùUS)éïso2žþ\d´VË\¬)%)/òTYŒ,üI-%XL•.>õR×ÍX:}ö° ¿mªr´VV<Ûj § ³ÍÛÓp|>">5òC¿jM]c,q+–5\)ÎaµêBÌ)Žõy“í—ªilyÁ† 졎Ý%ŠÑå•¿¡/DVäæ:fpv7X“·ÂË(!û®;jËaºFï¾ÉO§Bâ¨Wq«;î¯Á“àþqLÒØwÙd‰,C󗺂?e»C°ûpo›oHäÝjúûã4DÂq\¡n`-|휠,pM”ù±ËkîÕÌS^\sž¢ v#¦ºzºŽ³…S©ÿÍþÉÆhí³B·áãÀ fóˆ“4÷•§ ÙjÃRjqµ!UÀih{>ëâ«´î>/޶w ×9`‰¿ÄŸ­‚StR ñ¬œUÄÀîʺê‚„ŸáŽ¢QEuÏg8ÚÔæÖv[ò3˜YõÝ›—Ýp¹u4ç]óÎågY“ÆSKj_•Ã|¦ønzqZN®/t½“!YÜš\™'Hç—‚¤ ÕNž—8`íâïâ è*Öðöº=ºAl±3P_.ŽTèÍôcôz Yí¿ö®…zè¯ü *óÆjÖ÷ªbRk¥…3¬ ªMîFcóÙoWq‡Ç˜a”•Çúz·¹ðˆK© apNµlžZíãHÝwÁ)’‰ë˜f¿)Ôz¼[H»r£åè–•¿‹#ý(ï‰HE''—8%mV–ÐówÇy­=ܨ7ÏRÔÇ*…xÆ í Õ•¤Rôz5ƒ\.y ÿÞ–%yõ~Òò?jcÕK4Ÿ}«åº:ç+=öÀwÜj&Ýu²n¨NÓ†¨ÈžÊ/èÕÕ+&Ê]QÐX2zQëûþs¾ä¡I–Ë 4,y™ûë«rX*& o7GV1÷Фí¯;?E+”ì»Q.§Ü«öm)ÏB}ˆf<«¼rSK&í"rB“ÕüfV¯‹ ; ]M•ñu´ðoá"¯œ.™œG8ji,ùE“BHØNUZ‹oã@ƒ!™}LYíô¹ªÍÕݲë’9 TØ,µ¨o5ÇÕ=|v¿*ìò泎`Ýå?LøafT²1 ]F£ƒä3óz@ÞšKYõË<+›qŠªi @ /ÕAl[yo4r’€²ÁB»vnFQæÅÞ[IZ7õŽô°F´t±÷Íɺl[õ)çùaÄÊ¢ƒÖÄ¡- ñÈx>ûU½ôLŽ#åJØã]1¦Æ‰@µÎ*a·GÃyé¹Ó˜W´Bed‘*ZB®v™ˆáº™¸%*ÜÓ6=7öý€³>¹ËëÓÎ\Ù¬Që2ƒ«+›*¬¶AvßuK71˜ |ø‡ÅDý³1͈n“« j/g¯&‰$šõ¿ÿó,å†Ú¾¥L÷ÕÞMѦƒ(Ž7ä\¥{ÑÈ‹có:ï”™gþ½¥¯P;¡¸¹Ž#ÛåÕ0JØ £ " £ äůÂzÁ˜bGßs¬¡ªÙÉ‚7y’œí®.Åf†ê;t@Ê|ö£›ð2oUh´P»Ïºy )ÝDfØîmÐb/Î’~;pþN¬òÙ¢-Ÿ®sôž¹Ÿb¤Ç—ìñ¯-Óêæ[i\êªÈÑü*âN*­Ã §’ƒ®ÎìÌnÑãÁ¯es¶§´=òZÃÝòåŸÅÅ"Úœ 6>‹¨f”v™4V2–Ð} _8j5®È7Ò›%þ0¤cßá²iè4«'%=›ë7í ­oêF¼xÒ|w‰ae¬PÖîô“ñI[¤“èØ#Nõ±–ûîè™^™{*\EËú4;vž€ú´>UZÌÝT±®Ê8b-ø=JÈASszœ8ƒ/á=µÑKR^IV¯Q@G¥Œ² Í3¯:ÀDÏIxùA?ÂöÑøí-ôßUsšbŽÅÏn¢”.aÜV¡æ¿ÓÇó¾Øu­Ô-äå9æû¢†k’.§ ƒÐƒÏ”ÅDÂqºÝ,ABj7y³cvÅ_ÚU^Òš°ï§\®Gºìû2\ûIÏg˜û™s2L¼X9œ­<Þ2,ÍGQ·ã˜Å#7"¬Æ_Uëñ wÝ•,0%úƒ"©XköÚ®qXw•½šam´ãìdYóü¦ìa.¦c¿ÛBg»p3së:Î#©~X¾Ù_äcîñŠ€/âLŸÃçŠD‰—%vN‹£¢OaàûHà\1k,/¯þfæmkñ«Úáƒ9ËXѺ÷÷"†<„è85%kLâ(J\Ú_êø$s±×ç÷Váê?c¿’Qªy7+Ò€ýe&I. —ÅKÔö°ÄESWQ8ëkßÍ»CGZÁ»®„Zôz)TåÎgWµŸ6ÚMß|7 áQdÙ£-«Sƒ¶#×(<2Žh®âxÊx£ M@©¿%+D¢Àê\M1°Œ÷RV:Ypý¦Räx¨É;õ«\ïÚº¡,ÿÒÓZ¸€d·}c=äýõãzÐ%³`Gxíwæêm/•7}°vîcÓéfióÝnawß÷ƒÀ‹áߦ¤à›%<)Pè8kDyêÇBX¤·ßÇmHHU ÜÂDyØLfhŸÉ¹G_峃ˆÄ%Q ‰1á•3ø.Ò’i(TFÅJ¯%Æ$ø.»ç‹5G ‚'©,lc U üuH6àµ`uà_ñø€â=<=ƱŽl¯IÓ£†|V¼@ï]ó•¹iNP;³ÃtìÎ0O¤ÿôi_ÔùìºÇº«¸:SØpTØ<—ï7HÛ™ù+…Úþ`¦VÓFs|G4Üͦ–²À7^”§.‡o˜Ì1ü>1#‚ýûˆ3Û‹ù@Ù5@‚éç³¶hO‹jñµ4aJ„”Ä¡‡· ë­ŽU±ŽÍ=Ó~'Šüï9+ÿ ¡bô&ömƒ¬œ£Åâwc‹:¨FÃØ bÖç¹_Êáåv› Â¹’…Èñ„¶Hú(h'ÆŸ#Þh,³ø6näõgä'o†Q¢^22{½É•sŽÖsýª‚dŒÈ¥ƒ†p>ûªS9ßçÛÚ¶î†nÀ‡ÊX'>u¼Í¡ù–Ù©?Ö)öÂ:„ÏðÛÑu¶ ÄàÅ®Ö=“íÝÎ`ÀÒ4¶Ì×]Õ·n·go-ÒÆãÑúݦzP5d:Ùf,¦EõØ©ÊÙŸ2|À½ÂàÖó÷U©ÐrZ÷g7aТ ›æÏ}?ŒÒŒghÓœœ2ë«¥0Ïת¿á‰ò½µ(¨tD—ý5€S·zÐvrzfqšˆc 3ßc:¾5‹¯ÍNÙ𞼯á½e&™Š¤.ïi?"7õ<Ö‹·C¡4á{Ö–Âãõ°ß‡þÄW‰2ì‡-ÓÔ YfŸBÉ}b":@¡a°3§üõ1>žmj¾=yýw¤{_»ðbs úh‘š‡*ï¤(§è²›Y[†O3 é> Içƒ\’ù쪹ÐЊ¦'[@ˆ(ðÒ˜%"îtyè[n­^GðqVpà™zèÙ¨µv¸ÉË¿¾q‹OØBÛ‚f\7Ê\—%ß(dbNV…ÓIlXËûÊæ,îŠ_éüí7—¦¨÷z/ŸEÓ´ÅÞBHÈâ0 3Ö wƒ:ËþDù‡RpÐÂlÞÔB5½‚z Ði1…c±ç‡ʲä;¿gN;òMîs¾æp}¯}—;3SÙ]‡òÔB»æv>ÓYô]Ì£F¡-a =`ÀzôåvÔ—õÜÜu,Ž£LÝ™L¶*·ZÚbô¾Š•üµWÌØ9 ‘ïûiê²l¥´K³”CQ÷­_º¦bsõ|ÒBKü"Fâà¾[2Áç3•d¦•A…‚Dƒ¶×ƒn"ryß"¯NΫ̛¦æK÷Ïûp»û›eXˆÚ·m‚ªº*kZ ïÂsâòº‰WE­v‘1x;€^H†• •¯èäܧQú²é™Ï~^îôþ_ZÖšDðµ²pËh¨$.Ì•tØ–ùID<´/mÑRKU øÕ V{¸QÌŒ@Þ+F òæG^ û½”ÂÙ·§Þ´w"ä`ñš2س÷ 4õaûÂòB&1J£Y.{‰OÃÖi0Ì…"*›U!²ä10_à‡V“ïGgÝjßÀùìßm¹>uÔv‹!1Š‚4f¹\ÅÁ< ,óÕÞÙuªÀv©óARÀ}åcƒò¯wÑB\Zú©(ðÝ”Õ"ò¯\Ææ²n¥DCÂyÝå'n]N¥¿A‹ ýÌ’XÜÆ- ©¡ÙræÇ,^ü>Ul&=¯EÞ\æ%* ²§Aµaàoß`YÏEOWö§ 3L'­”Í1/ gE¡¼mú|n멃'’¶n×¹dÔfÉú­Ú* ‚reÎ%‚ÄCOßi…hæ¥tÍØ6\ýû4©¦Ÿw«¿vÿ\hš¥å¸ÅHyfÅUkwÓÀ ­íµY³×Äÿß“éÛpà{çA Â¸í©;©‡Cj—SºTEŽž—u÷A˜å©ÁSàY¼Æ·_ŸF©ü£û– #là~è‡ÈQãTØ _·Í%öÕ4ÉÑ–“%×<ŒÜDUQWŒ¸R®/3ô؇nØ y.EÚs©¤gæm=u)NÝ–¨T^ÃEŸóàÓŸy¹AÑ 641èª@6&ê"UÀÒEÁ»g¬=>Š¿NUIØ ^m4ºº¬˜­b[‹þâæ‡F¬±S!L%–"› *8ƱB*eãü¢(3pJ×ܯviƒ…¿aÐ$9öM¤í"Yä!„oÖ‹ÿZ¯+B®Vcð'zLïä…}4|Ô cß–7‹oÇd‚DèA󛲸@[•Úi~1—;P¥l#ÎLŠþ£‹ëÏvI JÀÌ5ݹã_Ó†ï#‡’$ ¼Œ¥jPÁV&f{¸#V=<Ó^izYBׯîÄv—Fß Ý0áeÐvÂI§ Ñš=þ…œ\xÛøOELÿ ¯\ÚˆAhÊiÊw¡*}V/”ÀF> ƒ{Å7ÎAD5g:Žø!ƒ1~Côÿs"nW…$'œyÒÔð¸ëj'¢,ïá®Xð–øX@OL<‘ûGrÅ;TAÐ$¯ÒÄŸrÂÞãä>¼#p"ËÞas ]óyÜklO:ÑûW´!Á–U¹”R;hÀ›æêË|µ?¥7Ø÷â åÑÛH/†ḩt§“f豕&UK:Þ'ËlG‡‚Ý23-ˆUæ&iÆrÍØä˜ï2Jè‰/Q·ít OÓ^ÙxühygzÌ;…ç«õ¡oö¡±du_KÌ43Áò+íõ|΋ê`ñѰY„Ür–&êè¼"øžë¯ºù¯S8ó%«B®Óâá9CÝHb:Eõžâº¹iËdK(¥ÍP[vÃâþKÛ•4·,é¿â[_DöåhÙîñ´ä×ýì{âÝŠD‰„jLýúɬE¨LfwÄÜîÅJªrû”˜@X‡Œ‘ð‡ê÷ôе)áq½|Í/¤lŽU»‘|pL6‚7œäÍ˲^Ø\¶xl¦ÎSáõ×YõbÄ}³ãÖ•HÏÅ\.‰´ Xý"Šso¯\«." 'tƒâªéúÿ 5còòÁt ½°™ ¶"D‡ùØÂ n÷º±ž-ùyQ…ÃŽ¼qïß @"´ãhg1“†ŸÀ²¸E&®÷&\|jý\Y8¼¬ïUƈ~IŠ~†¯¶®6C0ƒ7([üX¶IÝèîÝ ò.5GT¢·7 jÙÄmßÓ“ÑÖn1€™—JÏÐÏDC~Õu("8ã*²žÕ©ðV‡n‰ÓBwÓ”¤Ë §1ˆüûÅX…2åKâ§E Ú±ýo!ºÜ6n5Œ×±˜“= ZÑÄXTC)©dð;Âêù9p˜%qG’Ôý/.!½ñ9r†µ›:b°”¿“7í{Û|4͘1I}1nø™yo–EQ’IG[·MDH|YimϺ³‹âûÚî5£"`ÙØÔ÷¸ú0ú-~̤á'ˆQ?• ò·Pœ ±{o¨_ä„lº‹ Ú…AND\o&ƒá`D$¦"crk*8’ëœáH½Df¿ó¿F}~&{²úµV= ϰӈ¨@Í ‘)¶ýe;•"<¶ªk‘(2A«_SäD—³Šú°!{Ý,þk¨×WàïCå%Ò¸Øà°Üƒú˜0PÄZÌ{^”Ðà sš#4÷$¾ZÎW„Hn{éªõ†±J!+²A„ÞAaÙB)Ò‚ìÏ3GoÖ A d*gõŒ%ßóÄQ&c/[ð̾­ yhÑuÒª²¦‡*U—Ž€ÁE Øb, Ò¬eë@m¨ÑÞZãxÐÝá­!5®Ú¾—¿êi¯xA÷n‡ Šv‚¹¨šn5;„0N‰Èd·Ö˽²`ß]K„øýj…sÏ;TnÈÓü1GO Ý‚$‘ ãC,Rð:óÕóPÑ}Ñ`¦Ô‘ ]z_½2ZåNzù¹ÝQDà Ìj»ÛýñdŸ’HÐĵ­°!yFB '†h¥±Þ;3§eG-õœ­4ÌlY§2Â’¼2žy*‚yµõ°[ûŒàqã 3J奛ËF/‡=çoñï¡ê_iŸ³_âÍ[‹¨@úˆHû¢™×·gÊ]ÖWvrðwA?5RþH º7±T>®8Jü8 $q!è™P™[\SÙfehz¦N£që·ð ôºA ÅbæØ~Uåšls¤ê‡N—ÞˆÀsg³\ª¼-d2YOûѺº“WÎf="Ì?ÛÃbt\¡ß“" R_6dY½X¥ZglÛC§Ÿ*YYv¾™†ð´„" ÊMÀÝšÖ|çk¾]Õ ²Á3À(ÁÇðÒh.Ó›¢ŸŸ%a‰4Èì2Ö=¡8REe+T}pŒÒ(±ø2LÑT“4— Ë¼èØžŸ-ÊÝýd¢N€gHéB§C¨Ê^“r\P©N#pÒ^v»±ƒ˜6û—åuçy.Úñµ5¢šKm`7ÎP÷ø%JŽ© Q¬·s΂˜[𡃆´YŒzÀÌ dqˆD–WŒ»µa•Ã]ʪø×%­©£à¹ífäŠ Ó¾}ÝÞ¶¤-=qóÎgça!“r6ß º:tî·tφ§'ÆÈÿÜÚðÖ¡Í{ŽùUÚV½*)H+,ò8ICQecÄ›EHcì-É+«¦•=©ö2“‘rþϦœY|hªoX`JÌek##™B5pÀºQsöë]“#)0g)Oc;ª¸0R&¡Œ²ö—mW¬+0á[õwì¹Þ0?Ç™»]ˆ —Ç«d‘4áɽ8§JÞÃ/¾#ÜãŽÒÖž)Xdok7±®—|ÿ°+»k[ø8Žƒ, É®¡¬nt7Yƒ¶‘7Ó«Fê^ùÞ,ì™Ã¤I?wÖ÷óÚIèæœ‹”[~næ20grqöþ†Úñ&СK„V["FßÔ‹:påw’E~ âQ@æ«Ô&v aíöúÂ=†û0på+Ò,ŸK»¸Ä§/L-a"9¶ÈZu[Â|c§êj«’@t^·VíThÎ1‹?ƒKènÓÖåânh^™ä¤i’±dù²ÃNLzPHÒ ×ï¹m:³®”)$´œ#…ã“;«hŒTÉ•[‡Öið¶HÄÖú»»¥¡T›¹e¦oÊ=Íóe  _ÚNu‹Ï3“… [ Í?!ù.FZ×µ{rúù<öìo«bƒÅ~_ª•,”îÆ [dGÊœH³¤iœÊ’–3IƒÔŠ{uÛ”ÂH¿M·:bo9‡#ŸCÑ 4^ܵMû¹’Û¦˜%|Ñ÷ .’ ¤ä8ŸòTmð[¢çxAìân:aG'-ÂR¡Úa´ï³pÉ÷µ}©™™ût #s7´q×Qó…hÞÞí¦ÅùÌthXm»ªãü4yŽ'J]lÕõaT›è-ñtîèp™ù² N}ÞÚzËéþí„}A'y gmµöE1¿oàÿ¯È»éò`8'CXÏ„Åý´Óœjoúq!kìJµm{å10?gñ±z%—åY¾Àûå²íûÅ19rÃ?cQ/à5K¼ÇÖ=â\]‰óܨ]Æ{3¼§…'àSìZM¯3G øõ¬ÍyîÇ2Mß-:Å{[çØôlÐi/fõ.ûT¿2õQÒºö•Ž»[:ÆÐý4åý*«úÐx/SáÏ“¶½±îé…>ÃÿSW+zÚye¾b®ßÍIúݼ<óþ%îÜOáDE´9µlõfç ²74æ™{›¤ïã(æKõêoŠ>¶_dI âÍ‚)ʳœF÷½¼t*1‘A²¼¹Ö4º}±•ÀW5Ð!†YaŠÄn–CYâÜO»:ÆÖoô ÙLðd^æ,Fmúp ‹@HÓj òÿÞšU{¥ÚW2ÌݯuËqTÛÎuð¶DÝ“ŸÃ7d"F`õª¼•±p'{«#©jk&|f¾ 7„ óûÄxÞÐcm´~kNà¬1mˆù"…YCP>»™s»¡ëÔÁ+Q¬YÆ4êö 90û÷˜ˆÐ¬œàþAÃøõ\$yóyiXÄv”àVEòÜtjw@ñX˜ŸªV俱dOÂêó\Íï­‰^ 16“3"8W?—IúX…[UVQéõd;,q’ ‘Ô8pïVsês–öÂ/vOƒa~S{¨ÌèÃû4®[ùiTûQš‹xÿp³§æð§7§Õ;´ˆ>Àå(e 㣹¹Lë?ƒxÎ 7ž‹ä~–'"šncå&Ü•L­¨¢„mÓý+b6d¥vÛîWíD þ½KhaR|C”Y(‚ü,;Ý'Äx™q$ë k½¢¼ŽZ6Vµ‹}érÈ–Ça˜‰–EÊtbÞCíFF¢è™¯êFíD±}ꦈˆË™¢ʦÐÊØß¼»×ð᎕èçãjŽŽ6 Ò ‰E,Ö'Εh¹9_ز:hpÿ¡}ŽpW=N£°H“"’tK8z­tèf)!¼©At«7*ÃËÂk H¤4¶ÞQhžWlªì·ú*¹, ˆ2 ¬OAF|«K®Km¼"ÏíhO×# ±Väu„jÍ•‹/!½Q‚¾¨"§ ì¹½'Ô!vÖºÆmM©þŽù·^ÑIž· ~{GŽïeEݯ­µ²{ƒ:1臊=Pe‰ë¯¶Ú ² hÛ(ÆÒîû›9;m¼Þtľ¥„ˆl‹¬‹‚·y_îÞ }À<«z+Ë%Ö€ŠÔ4OTÛhDaq´ÑõÇõÍ}Õ÷y"Šü(E+*ÝY™4¯›IÕŸ²‹Ióç?ûv ÅbÌ)LoŒœÙbj=[y;¾õ¨¥ž}±<ÌÂTµ4ТªŸèE·5ƒåJ¹°Èò Š„‹û•öS6Ôé+µðo ý£pMe™ÊTtœfá9JoqEkuíó@Ö× î†a{î{¢nU†>§ ™ÞÃJ6“Ñ^2ú*6êLÈ÷nhJúF1îŠeþÚÏHQÚÆ¢ûKµ”óä=ÊXõº¡ý¶¸òü˜5æceú)¨^£(”÷°™!Œ/¤m»>É…-+ëðù(¬N—äÖßN2;ÅY"|_C»±Úè†pKÛ›u¶·å»e²cúò.“¢Òôû%*ùÚoÔ)Y—Ǽ¨"õþ¥FÃŒU¸9>lŽÏré×jŠîÿG*÷<& õ¦³0i®´/ÚSKµV•;#‹ڴHåê:-ƒ°Ýuxfil¤nÞ䋿ž7\ÎâŠ8‹"ÑÓ!©ÀÓé±%$W'#Û‘+£ŽaÜÚð3 ýÔ—é7>ëz§"÷ ¾”‡7Fy²f˃ÐnÃÃ&Ïo ÞµùT‘e¹È“i×n:M [Û£S¸¬»:ÔÏzšZ/ø>zî¥ì9„¼·µEGí™*îDi¦ý\¤x;ºjånˆ¢®¡dl;HŸ¶Û•aRá\˜dÊpb}{á ÍÈ’/ô Ðì™Ý© Ÿjÿ.3e’á¼Dºíš¨QÄ ‡ÿ†fd«#¨ÌUY‚kÉIvp'½ üîgõ°Å±” P…#£Þ]KM>Fw¯}õ8(É{õ\µMN,—ÇÅ´è?´K²xûÐ"=‚¤†âØñæÝÑ5Up~1âüòBô½nb÷ppõH$"´K¬_᤾ XS ëþ;VãóÍùD(0- N™M‘yK<ä¿PJÝÐo’B6èPtËÈf ˆctÄ1&bn!É+E‰à4¼‰ÂýºÏÃö™!¢¦:Û×Iw q&‘m@0)Vðq(x@·–í.ŠìS‰"Xd%s;'ž1&‡f»¸«:ÎS2Ì“$("Ñ»µ% %w«5&FdÚU{ÙÜ¿fTª§'Zgƾ:¼µqU*d‚£ºÓÛÌ-bÿ|$P ‡üŒ“äqËDfGÔ7«£ ”Ó"ç¶5ú*;ƒÂ-ÿnïõjYI÷øŸêÉsvÑAß¼ìÆ„oÔ1¼&`Qä‰pHñ´™˜(Õ-ÛžPÏ[* 4ÔŒüôtIy¡¹i17ïPõÏ<ý·z:ªlí³$M#Ñ¢mÓOQgQâ‚]E2rÅýÌ1õÒ‡Çɨž‹PóMC’Dq*JÝO†Uéé)Mì }ïâk/n#cø‚Ô˜ðoÎ÷ê!Rå…zqƒõñLdñRðL7œ;·«î´œ…Y&½#e&E“¶kûÍ!uWdêyòŒ¤Æo¹×ºfÚõãz’Jñ_sóî Lc¿UËÔŸÁw+“w:¾CÈ !85ÊH'È1œ^åýÜjöž1¬Ðqb.Ì=zgi–g’vÝiTCKÝØ‹¡P(S‡G6[Õ™ÿ SÍl«Õ5»ÖÈÏü( "Éþsƒ3‰ƒ™ILêij ¾mqÊ,„éÓ7wräpI7 W{ypQVĹFƒ(žÊìÆ¼Ãìl»´ßxýûþ…“tü€!r‰öû/PÝ©ÅÝHaaž›8„.I´ 5Fs©{>ب§¶ÖȳT—[†FúeõÊ—¶'× CWNæ/#^ŠþZ³¢ˆ># Ô k{»j*Ù{Êh „ŠI†é!œm/iÆOÈŽ!WG‘œand¾/ƒº ŒÃ¥õvpﵡ×ÞÞÈöHõU¹Ótø=Õ•á+Õ<ŽÒ4 «>­ÌÐÊ–%<2^OL¢R-ÙÆ÷ŠÒ(/QÔáÉx)+2_Ôü£ä²õÖm·z¥¦fñ »T8:ÃZœŸ9&-gS ûMRÿLlç2`?OóHÄ,Õûšˆ˜Í¨®nLµeŸÉf¬‹rO߯?Û™bóÙãc†ÞWé¥Ð22Î̶z"Êð7ŸuÆ¢¸¾¨g=ULž^Ú|c «ûæÝ Mw|RÇi:“&ó4K#Q”-|@»¸©·íFº!¼r#Yc ;{»b¼ /h,ÓôØMlˆ+™Aìë ¥™eëk "oáíìµ¾8?CcO±Ÿ&Q–D¢zÔ‡z»C×Wîq,J·^ßDŸ(Î’è&cLsT4Ë2\F öµƒ?Ø2×ÚõÔ|r£4EüÃÕ©Gº. t* EGùkMVnw'Ô<±×Ãô 루$O®´k˜ø¹¤_vý3P/ãì.n ˜=ø©TÕŠÑ~zä¢S¿±fžžˆê¶ x¼$>ó£»'Þäöy&k Ú†Önþcn4z¡#aÜ+÷Ö$Š+½ƒ¨Aeêe[ºŸ¸FaÓ³’^²ÉâÀ‚dŽ"¾ÑQxáò¹¼y(ŒÈ @ð* ¼ÓöÏOÊàfUG¯ì+Æ—•Ë·¶¨l°¶ã\b®‘eG˜ðâÈÔa’>š|"˜å#šÎÀ§øº;¸Opk†ÿÞò-K ÷»³^1þÙÁ¯(>ÄÜÃ4Œ‹Hä{£68ùÖ|§ztèÖªñÕ­ª}+DÑÊ^œÃȨqónü…@qú{8ÊD¤-W)Cê7îêÉzãÈ@š©aYÀGF+b)S·¯Iùà¨T¤Yƒþ˜X {[øŽ‘>Í@lìT»’nòyÛHBã #j±$W´#H E’óìL ·Íísl– ó«’mO?«ýžSY5Ö3T]c ²ùw‘„y\ˆ^ê%ô"ëe ›º ŒzåZø×gwÖü‚¹}q&Hr|œ›!´—˜âzoiæF2Å–©høíÅmÛï­¥ØGu¼ˆWŠ·(?‰EÃoÄú7£W¨ûë´"ÞÎèHË’f:)²Íÿ`wzTžû~XˆÄÛRyÈ1pã 7óñ Úg5Ý^6OÆT‹¿w‹ï\–€7%IÓÿãìJšÛF’õ_Ñm.ûrl·ÛÖ³,·ŸíÇ›[‘,‘A€Æ"5õë_f(‚@e!=‡‰ž·ÝNU¡rûÖwW‰¶h3nû¥P`åÚ}QÖI¬Tñ?PùíŠÜR»¤moþ³ª«µ°4‰Ÿ$©°”€û¶Ðò™.,'aƬÄ:çÊ(–ÏbS“8çEo %Éz{s_ž­Ïµ¯å4“(ñS–…!Š7ˆzÚw¯j"Þó^Ó’,¼?S¹Q„ÃñÝÞ ¥âåYš ž×˜%2„w24/iÊ^z+68Æ-¦P¨‘`ì‡ÆÈrhì6õV['M † t‹¼ä^[ŒaLº3ãùï`Õ¸ œAK‘²tÌ´ˆ qh/¿!8€^…•­µ7PÇ–S§no~èí×ùã«-ü4?σ² 'åÃs‰ÿeWS4EKxÓ™Ïý^˜=+ÔW;5-œÂ(F¶ÚÓ¬ ê'Å`æƒ,û­šÌÐ-ïtJ2Šl`¬9ô΀-ñ¢Ðã­í÷:Ùºø8¶µ9»?öÕÞ=J·gêëý‰¥]}ÜÑl˜¿”ƒ<5º i¿›® ±4aì¥qƳ$n‹ƒ¬±µ%g¿#Y·›¯‹ø!ÙÒè{žÂÉí¶Pߤ½Ù‡ï1‰³„2òêê] ö‹ÈÇ-~.,’5&<˜…ÅÏÕàÍ ·t=ºI#h”„‘Çb® Þ½CN4W;²|†4‘¬ýØ­œ<—×XÔ)‰yÕpΪ|ô9B£‘C7ÌÚ$¾HŠ“’)õ™–ê%z¤"»¶Ëà´r{ƒÿGϧþeà}M!Ø;ò$•›½»í‘z‘N› AUZö™§E¿±€¥-|õ;Ù¼Ö[ça W[®išdðærÂÛÉ-fFxKI´tÙCA׸í ^é·Ù'ø”ÈâÜ®>xiPœ™µóõC›AùÃ# þjN1ÒXq~Èû íÕE MÔôNì ¸CHŠº©ŸÑXK}Çi’³8ÀÕN3!c…—˜w7ÿØèAê7E'BûÐ@å|’E'"ˆ#è‰yž1kZí£üLô{ùLcL¾kåPr$¥ôÛΖÃjAÑ4Ó4…›ÉÚtÃ8Î7™—±­ËMÅ„e|«i!Œï]½'E“DÕIT9;Àµµ¥¦óó €(9Aꑆ»Ghé‡u56Æëüm„Ê?zËn_¹3ç>_ïk æK|§§C_mj÷qê 5R¨íáI›‰·ZSÒ-ˆ…—¡©PJ–^a ÎJ`â€ëT¦ßKâ ˆxh°²Eéùi®ºlêB2…N¾+y*Ð7H;íFœa J•YîGYž±Ðí+8*å³iÖ2oP¬—×v ,àdQq™)PR©œ; ãNÇÆèäÄÂdâš¶®Bóämõ[K¨÷5íïg‘ÔŠ¬·7?ÈÖÀe^Ñw2ÄqÀF7Š…Fø+(´çuO5°¯tˆ›85°ïôqC¬™~K?)O}5ö °Ëì•ô®èDNª• g•c"+\·ð~d “,ÏyNxp{íÕI´Fº2t7¢âïeU‘5Úížž•®ì¦š¨¨—³ÆŠ>,6+ËDs榣öu'_™ðçŠ=:Õ¨<" Ûùû ­ª‹i‡?'yœç x P t cÄùŒ•p£=ßÛ:‹xÛð-N€5Š/diÃÌ󓀓 îì+Ïœìƒð»Åƒ§ÑomõèThݤšäü9ÞZ‚L²$çÙ¶û[3ÕëRÆ!åíÀ+Ùà :µ–º[)Ï‹ì,A¡}?Î3Ïã´Àƒc¯»*EµÞ\ö¢®<æ}EºwcYL}’Õ~ZE_5N¸)]”Šs/ üŒ% ÿ(Ož™V ŠE»Ç}•)ÍVXäËîçïùi_ûÝ“‡ã°~û±ƒ_¶* '^‚#E–•1ü¹Elž~—XuŠ$f]Ô/ЃQ!ÿÆã‰©BM9FFصŽ`’EiÆrÁ€.šˆ›³<îjè~™ÛÅo}G–8Ú‘Do. ¥@à#‘¥æµ/š}d¦°CÉ‚P™Rßv7ì¤EXo²WáÊbÃY¹ôÓ,Ë–̉X­N©ù2ÊN‹^~h;› ÒB6Ôp…Aô‘~X’0„vÐcyY6¸®²´4ÇÙû‡’R‹Äa¶è³…dð/Ö´¢Ø‚v':[æKº ù3yÕÖ­|לhW¹ TtTLeÖ!̯3»—ø¾Ç*½¡>) ”Éu‹¡Ÿ‚dž‰aWâÑTtf1ˆ1˜m[ÞÞ|ìË­Æœh!»…xi>‰òœ5ëFÅTY7(+«"&ÅùÔZhÝ ¬NõH’}‘JBbØŸ¾9 Ì…'8¢ªS§íŸmß‘s`m¦àñrà°‹!ûE«ë})‹Êùþ¶Õ²Tl)3kÜÊé_è26”+á¾ñhx‹B»øÀ,6²šc£ ¹Spﳑ¾¸¶”ï!#b­/d ·EârsvSÀÔÀûV¿Ðzå3%ÒqëB Ï*t‰!4Œ¸žlKû~„ÈbæD£·ìzÏúãDTg^;£j黎–ÅÚ²^‹‚ ‰à¾rR?œNÑ"Ñ´“-Q£C{Ó1ýŸ¡u'ïì²–Û¡²Ï9‚4RÀ"F Ø.Ð! žå|Äk2º/P½·“ÁÁ(<äŽU˱" š\Ö¦éW…tw'Ñ™óànkÐâàmi¨þ7e©@j|#g€ÑáÅÐé† KùãµP»÷E®H—Žm+¯ô­€ ÕPllüí{Óæüê <-‹_Bö‹Ò„%»÷|Ô3IóìPBN¯2Íx}aYÐÀË¿*¤+GÎ[m +ÑcQÙšß•r©Iðü<šÅ…?®’n3Ûv_.åï¸Mþ½––µŠ]˜S÷ÖQˆÝ—°M»ÁÍž¸ŠÒZ[ jLúM¼^ó=­Ýˆ"Ö< XËv¨ýD)¥û2S2/W¸k5Hšù±Á¤#§ðæg gqͤyžx9‹g~›“R·ÀÌc>Kmmdz)²Ê®(2%ùáé›bhÆhÿÂ3CUælù¥|ªQ¸jßbcËÄòþ{¦¯;hÎ$ê®`LÚ+eYÈ"Ë/Mxòx«r" y™>œißî¶)™7ôƒ°Ì¿)~¤Bý, >D^”FPtrŽð×afqÙ€µÂ]Ÿ‰û¬ð~U—‚|b”´ÜÐ),¨Åðåy,ô|]n…{˜¾Ö#!9|` á²ýS¬>½?{l-ÉoOkYÞÞ .ÍnØ™~Ëõ<:”‘ã<2¨¾÷ZHD–BĹUÞQ®¶ÅaÅüMT“³ ¥kŸœiÓ%Ÿuöï}µŒ`¼Â»Uº]#ÑÞ\Ûˆ~)à¡dïì0îÓ9Ã]k@6CyÎY:MØf/‹“ÀO9GyÜÍwéã8q Âäá?àÏͲþ^R»x'7•hnoQv0^1~O¢ áן%š¢¿Ì{6·ú%…àNñztv®-ÛûRõœCno´ù•®^§ ×€FQ8éäGß8ñ2sW©ÇpÊFžg P÷¸Û;…D&_[ÝdÙ±pe=&eíl.ã>–f7ˆ®oð4WW“X+LÒeê_8°¶´È¼³¨žEAæñ:Éݳ‘sti#¯=ºíæ}ZÉæÑJŒuíæ™ïñ¨k;¤ü*5Z#tº¹eÝóH‡…°X¬~ª§Rãs;·ÍÎÜÎs¢gyâ³¼:Ï ?ed-+ƒ\i}Æ<×µûšö·ø±›jWÎ!Š#söyj,ëV/‚šó\r¡b+*Íœ 4ÙáŸÍÛuÍl5Ö4Ó¬ö<–L†§é$oֲР„¸K¼1´Æqι·[‹åSÛAÃÁ:Ê÷²|´qÔMâ%S]Ïýô_ËX)q½;UòÕòÅîSÝl¸õ8.³,NAjŠ£ú,¬qŠ¡a¼—r6‹Ø‘Å~æóU¨„æb§0s¤ºÌÊßh²îAl7(qÍ{z H¤…èmþòcØù0+ÿ&e«ŸA‹Å鮚z½?¹»ZRc*¥8èë1[ͺ֑ôbò»†´Ñi©“ÅUUË8UªV(u!¹R{õ¢ˆ´ÒØaßÖ•Åxu@6ئ(°X²ÁŽt¦£:‘ ƒ—5ÍXfePgak”›¿ÍúØÔ­X3ŸÕoÅÝ\©8ï&ºšãü¡)ëv« ?‚w4a­«Žë¦‡—ލ2ï¬.5+Î̦ؾ°!‹ ‹ôнè»Wxx¬« “$dÕÝ¢¹Y:ø—.J™:Xðà ©ß‹É4Q¿TŽÑ‘æ:¨ÎÍcIëŠF¬K›%wê=4¹bÍK/«eþ¤šdÜÞü¥XæœðÆqƼ·ofs”Ã5;¿¤{µø’dÙ6¸ÎÕ’'îÐþ¼µ8Žòܶ.åF{q±ZÕLŽÂƒÜZ€Ä3öoŠ|Å¡X*VÊkþ|—Y©j3Ö2ÊYqýÔ y ª—7'y;E;ÈâŠMN\P€ÀÜ=˜´#ñ¹žé0þU¬h§Ø÷³ y4îq6ñ÷¿ {ÔC¶E",dâ(caT@´VÂ^OÝ#ª»ó†1ðÈð¾®':Wƒ¶Wau5qãí,$;®DÝC=ÍG—ÉÄ MÇÆ‡‘g÷Gµï« ½_Rn+ÎÛÑRŠ…Q‡9+»Ùôœw¼¡LÌéîìÑA¶|ZEŽºœ—­™}ô„ò.X¨Ze„Hâª'ºÚ­¬yJyÞÅ?DדßûEóJÝbW9Ð<6”~€j:qÂÒˆß`éOoìß$‘Ü•êÜy«l¹îèè½\ïI¢ÅYóIÃéáM‰s…_k?Wa•µlb^×? Þ¦°hì, Ͼ·7oÖkêÒþ¯ÆÐqg)|˜q¾#m"2[RïêV¤_1Á5 "OÅj¢…ަ¼ƒ2›½”N³þÇÛa×bçÒxi¸±]·••‹ízÌ0yPmAÞXÌDtÚ&fÁ‘ËËÜ—äÿÑ4c`'4;à­@¸KäþÁ¥UÕ¥£M,—ЋÓ$e­’„í£{R²¾î¨äÁÙеŒN€ïûwý¯ž*_þ’ãôÛË|?ÌY„ú²®6u噹Ùkkã:Bk_ðƒ*)[X½<åäã\ÐЖ'„—Å,á(Ç ÿrŸ‹µ¬:s‚/ÚFÈÒÝ©ÜËÓ'Û-ZqÙŠë‰T‡¾ÒƒÝ¯s‡IÁæ%YÈ :=6EGA¡ øè«ú…Ç„²‚ù?L°Æm„°9wszÖt×+#°7ÄS^ÕlÅÜJÀØÝ‹g& ÿ¡†0IÛÙO„ Sbœ1à Ó2?ëÚDJ®=£¼ÓïÈtß‹¢³€fzöÔÆÈž#´õåÌú§¹jí%M´Z¬–Ø÷- @Í$>ˆÓíØhcØ®´ëÚòôD~ŽÂyœÜÑš]ê®×eÝ)åYÄj*7½fyGëÐoÁíÍà 0(æ7S“õë,‰Òd^Â&ï:Ü3ˆ’°à€Š ® ÛÕ¼¾÷“z éõK±¯KÑSßÕ/òöæ«J\¯°åúqæ{1§€SÄÉÆ˜B‰6ùÈd>ÿ(2Ì&´Õ•Ö%ê T°FZ™ŠG;Þ}L Ї~âg¼ñÚ£²Ï&F† ‚8«˜«_Ù¬møÃÖC~n8¶X¶ùõákË2@v#k(¼ehÖ¬^ÌÞfÚÆ FÜ™eÇòòÓ¢šB˜@ëä'®#&¡2v7’XÀŸŽ¾Á:·~2½£RÖ0ð×p~¨U}#s?Îó”5=íQl××?{í›Àëå…mÌôSl‰¨Æ†ÅïõbA¡ÁÑ%¡çs6b( #óu|)*è ø—Ý'qbÒ?‰ç‚ÎoKÑ?•ž£¢¶/.ðSå •Z½Íá&—׿>©L:È{Yèçó•‚WYžÖy–!H’SRoÄ¡…/®$Zy¤©Áã—¦¼6¾.åÁ’¿­vÄ £¶Ô0S‡,Yÿù`®ò³/Ì¡½¢ä "ñ ¶[‹>Ä 8V¾ØHÇ(r|Ý@g¥,ͧQ¶;ZÙõԞ풲ϞLLe–›Aß·mQ{6ðÆzæ²l˜å(°Í*MÞ¼h™Màì_g8«R%ßUD+òéÐÕÚo'òyÓ(dmÿ,ä¤3¦E*U/æ<ÞF@ÿÞÉ~Ú˜Ž,Èm±½'PIB÷Xzèb‡,Gœ´KsÃs€¸Ë~Ïà þhpÞDw:ÍTSñš1Hû.¤‚ ‚oχdÀˆïÌËÝB'Ýò×YnŽ á±È"˜ì@Ƙ‚3Í|y=æÅú¾±^Î#ŠÊ•26ãʶV LBÒ]Ýšz5ã]——P8£‘Ý* Y,«'ÐÀ@B_ ¾TÎ`.úR`îˆù€Áv Ò0IcVû=Ìã¹ó‰=¢/5ov‚¢ä yvo!‚;ï8oo.Pì’]V…i’°L–6.¼p_vÀÚêoÆZä€×‰—bSè…ßgÑì-Ùrw°+”…aÅ)ϵNßÜbM CžÛ7·Rž± yew3 ðøE­~«6s’û~–Äœa/º]e†»ÂŸ–ù”ZâŽãÙliËäAi“Êå€Äzçw×S°4ÌŸßc7kG‚ÓpXÝÿsv%ÍmYø¯è–‹ˆÂ¾½ÄÖXö8±=qMnM°EB ÄP¿~ÞëI,ýš/sH•®X-t¿õ[6gÛE¦&ú‹…jdðƒj1S¶çœr¥­!Ø ~íP꙲jaªü~-å<Ÿm%Ý+ÈBiv¨ÑW­Ïl€¥]ã Ͳ(ð91g¤’@Jl!5×ó¦[wŠ'HÓ°àjÚ7[4¿69qOÒøYR¥¢ç†gð,N¯ÕûC7 äÒ]£û‰“½‡;´@¡ci» p?/K8cöZF8Iæ¢l÷òû'año½e–õSéwí°îìÅÄmñª—Ð眞üÈNmÆ> JêÈAôqÌM˜Ø(re }³Æž3ÌÆ#‰4òÜ”ÅëjjFHQõj«¼ytcYîe,ŸñæøýNàóqNµDA†òTùfÐÿi‹6UÜ)»&aE°>œi“÷wŸåº49g®Rã°$èë—ðwôK£ ´‡l.ñ›²´M“,'E +¡.[]RœñÆK “`o±œ‘(m¤Æ1æ)L#«˜·8yWwÍ¡¢§º½ðqØG”‘ºÁ½u¡ Y3—½èJg#NÒ 'ÀsCKæEÌAg Å,­½aS¡þ£®¾uPéV·‹üjIà¥,õ-­÷žšÓ{qQqâÙïi Vê|&ß©m#ÁûYDQÀbÁõ”öü,{a<år/œ¬•ÞCü l¹o3D×Ûñû»¡ýµÞÏ «4<¤ÿ8‹X ‚:?ˆ—Bk±Ué0uY‡ý.^l\ñKÙI·‡È,Þ"†>Z…~à³à=‡ú„‚q$vÏè-œu}b{¸^>-Ê=³_ ~áøÂŽq ã S#K̹UÂæa(B¯&ý\Én£HÓÈPéÃ8´=÷¯æÊÒJb à€Q–²²¿,eU7™‡pô0äÍ)nTÝï”ì9.TŠw‹³ž¥5ÌÒ ö}&ëüea@dÂÓ}ÕE+[Ã4×ðÊüa3u÷+t©+ŽSVèú1´À.'+BӔǬkEé,•&&Sï®ÝXšßwf8dë¥ÿ¬|[$| ˜1g¡´TÜ)sÔT`v§”%ÏŠïSÝÊ=‰ù|@{ª`Ókíû»‡nÕöLéÏunoŸ ;¸a¢J?«–˜Õ¨”i»(²¥DÈ7]€\PŒe1_àO nÄCF¬Åô¶–%\qçTCØÚš%nÎBøêårå ¡É%o§Ý±UÙ¡÷RiÙFø^”¦K]\tíAV„ÙYßö‹ ò¯y*O­e¡Ì&Èæ 1ÉS'aBTuN7cî—–â„r(;\8›¿ç®G´9h¦Ìs›ª-Îæ^*•OJYìAñ,µ8L¡H –6ÊÍ¢0fÆWòEVN; ÓCW­]Qù+ü¼¯iÙæ÷ÂRÍ\è&‹‡‰Ë9Ÿ‡à}.çÑëÚdh6] #Ëš¯¿¼ÓËFêlý*òþMõ¥5õ“1|”Ùb½P-l»žîùøs-xÅ€Z¤ïi7Â~$¼˜ý• qž,‡­À~ÆÙM»“!Ü¥’9³ß¼ØóCwÎÔùlMŸÕσÈÖµÈ5ÌbfŸ;iø½ÐËxª =üº ¥|ó$e¥Öúù–¹ÔîÅ©³Þ›«$§}8°>¥=ï§î{SÅæ8Œ–”ã¥pq0Ïn–M½dúFÿ‡“¥ø&-JÜÔ”%êÃÈM¯idU4‚rþsYNÏènI‚V¤þ{©­A˜ ¸¨ÜGòƒ êºÇF<çÅÖ¾uƒ ˆyì%ºÆ8õ‹ù¢B†Æ±&oèfƒ™™ÌÓTŸ}Óý4€ç¸K©>ß5ž ]FPƒ±éÝ;y-Æædá þè÷ÔÅÔ ø—ìÒcéÏX~úÈ‘†‰qb욦y¼‘ë‚ÐP}ÀÙí# ‹ZºÖ¿¿; ái™¦¥t-­£ëFÐfñ\¸A™S¢T@&KRâ7%ïlï¹Hó;þºæéÕxtí¿ç±(å§cA`/‹¨¼®r¹Ï‹š©?—Ÿëƨ¼KT‘ã·˜‹ÁiœArdí¢PàŽ¸¤½¥‘vÐfÊ 4ôÊû­ Ù½%CÅ"óÃ8ô]– Bƒ|#Gî&ZשM®áuÜ9ÿ¡°(Qõü­Ûâf“1F¿¤2ŠYxàÕ|Ý|9ªDæ\05Vsªú$hM8(ͨ^÷R‹ëŠØR¬z<áy‡V†jê`z@SnZYIÃNöuCBz«Æ ii⇬”¨Êf^WWØïR3XçzS.ébÔ†ßþú 4ø‹G Yµ„L7ÉÜŒ…-¹ôï *ÂKZÏÝ„öm<0É<Ê$ŽlždÛÒ*2½Êˆ}åQ˜òT´ŸÅi%œÕ/bW7H©()o¬ÿoI¿µ/Ðu>o-€Ë¥Ä±ÿâçLl‚#õâ4㩡éZ'ŸcÍááp’z‡ÊÓ´•”³%1ôèØ…Qv\ŠF ùqÊ•íf¦u &í¦„>P™NS(¹BO܉Œz{ JÚ#³¦'ÏÆÇãŠ,†teœ‘ÅZ¢nbUÀ«ˆÅÓ³}Ò¿aVRø­°°ru‘Iœô œ]Ø¡©›ÅHdœp_Ok kp‘P#%ÿ¶;A+Ƚϋ³Íýòs¯àli1ŠÕañ¶žNØÆÃˆ„<´è¡×¨&† -qáL•¶¬¥«Øo,Ÿ_§Ç=I¤Ü ÉÐâû (?Õ4ò¢Ì9-ÆN¹“z„Ä›¡…ÖÜdÝj UjT5$Dµ CËÂËÜ,Y`&)PæÜ!÷FE^7»‚9ŠùMÔ´)Æ7Œ”ä,FSëí$‰8Îâ8aáÏKHRD›@o‹6¬ÏöÓ¦øcš Éfû(‘@¸lEo §,$,­b’¸>(qMýÄ*W›£Ê?ÙJ“§]WÑ®V¦ÿÌ8ªtåáÕÚÓ#R; SÊ®¹‰-ù%߉æp„½¡ù:ê b_¾o„ú“ÆÌ•Ç»éÄË¢€å«·ÃËY÷àsDÅQo“ûk‰&SÔÿc £XG‘Æ^ì‡,7 â³Ì7b*x}ÅO–µ²ŠyCvÛ\ôk¯åm'ƒ¦®—¥ ‹zv„È‘«#… =>AEÁ4ô*è-®•&yÆ0/n`²|([ NcMo”ýN/¡l.¸Ë—Bì[¬Õ‹hv5-â4޳… ôbb½˜4vÆÕ6Vh!Ëd^“u ›ûÄÈ ‡ýßÛ’Æ|3€÷Èf%Ç.ˆ·ahjËD<«ùý ‹¯ƒf2‘„‡‚عs£U%áyÞ’EMc /,tOm1#ÆM}QÉ”'xþ©kt|Ë'êŒÙf„O/I¡ eÝöj–Å‘Qj¾£‚Ç,×:ÚÀ¼ù3ŒÜ”ˆ½Êþ,"¨ïºA”òèLÕqñ"0/œN8øâUÞjï˜[;×’6µî1Dç8Ù9¥žÏë|ë• ?Íp(íˆÞãM3öŒ¾æUÍ–*Áe±’•Zu€…vv4úI¦¬4"ÕÿÔ©(òÝÕ ÒiÇ:ôc¯-AÏ«,å9\ܦ–Êuö¡¨úü³«ZÛ†æ8â¢òPÇ Þ˜³6ª(” €»À«Ó?ŠõÿE‹9“ºUni¶g­¹éÔp¢¥àBq±š®\¯6•×¥g™7¢X3}Þ¾6¶nr'Ö$Õ TD‚Ët3µDäM–ⶆA·¢gEìâ!ôjI;. ?$éA‹xR{ÀÇò˜þ Wµiã‰ö-òl¸¢yÍÄ`gÌ9ä’)Ú›ô|m‹ÊX¡ÂAMÂ’Ï+ÅTacÐ]ˆ¸À÷wUA#Ñ ^¹#¡„ÃÍ=j%qìz,¸!z°DæX*t £òXÁk{†eØ&·ÔÙd{¸¿ûÖ³lzÎKmcøAÅqp.ç.ƒSŠ¢%\1Ï nRhsâUä¿wE•ÓZðÁºØ®§(òÈÂíÑë$6k\hg·ó¬¤xyûEˆ…Gr O2ì­V•h4©Î&=/6ö}„MGq¶6ù~ÆÁ$þŽkáÝY؃F`Uò5ÐCUÎZѬĶ>‡¤öl»,kèuÚšW˜UAsпïq8b©hÐ;ã†Ñ5ôa’EL¿‚üN]óM]¾vð ™5xCccßZ,“{cöû»!³çÒ}X$ðܘeÓ­!äd§þe‹¶ÌÆ“n ÊÃWC^'S¥¬¢M\­F„_w©À‰ô c×Ïxì{¨¸¤³›E0YUb d»›ÿÅÞŠfNèÛN½@è÷oˆ§C]ù,ý¼­r?ê}kg’é¿WÈÔpžÒONöîïÔèF]φî¤áGY˜°ú¦}”V ¨ÌcþÝ îSÀã‡ük] àùœÏ©,òk•]ç8qS·¢œØrÔ`ó Þ䲨€ˆ&dêEŒìœ#N§¤ïï´~µN÷¢zš‚9Æ"Pm{¼ö·Ã̳/ [›‹òL«ã;oLliÌÅ⮽ ?° ±¼Ç ƒ0ÊÖôX0§ÅæÒüA‹§'øœ]^öË&Vø™¶Æ´õKZ]ç§°}?¸©è±ÁÂ0Êë3³¢¹ÖßugÛj?ëªÚiØïf^ÆM¹¢ºé”åG^âAMÊ™-ªb³Å9D3s-ó×ÉšLi’R’mÅOœÛ'ûÑ¿ú[M“›†¨ðÀY«!aÕ7×/ç‘¿sTCÞžtSÓ ÐŠþ$¶¨¢è†7Jây¯Ðô3§Ç©kåÒá«Üà>‚GcB  mÕè8ë]->ÖÐri‰œÐ-ùk¯¦ôE4„&TsÖ×馃’ã’éè†2¯{G;45Öš‚g/îltÌ‹™@«Èyˆ9ÖLUë´ÛS)ÌcQ>ù.o¥Ö›°åöê± Ã˜ŒÔ좀 Y¦bè*Ö“_þ€cqhŠ•ÓŽÖhVYA/Bo#…~ë-díÙ ÒÀMYò¿ÊÄÕ5ƒ¼–ÍêÁúh?Å ­6.h-±ËíMoêÆè®Ì ™OBºf©JÈO./ÿý[Ö4ÎòQë¸P/rÔQ%ÇI3 Çó$X¶8áSûwb¢­:}át{®&×\=’ó®ÃA¨5LY³‹ç„‘’kä„M(ž&²)tå:tÒ+wÞ<“rxq¥@5%ò˜ÓjJs!uß–øiì%)gFÚj— !< B‹ƒ–b¼éiE‹;õ 4*ùiíû3ÇPÝZÃTuâ€Ry g<³¹£‡¦„R^]Hg_wCa\»r¬eœaª§gÂÍj÷}¦’(Ôšå q”y<íß-4~(Ê}"öÈ ÉKø¬‚æSW–}¶ö6'Îù .óâF ]oè¹~Æ9ÛFù^8+YP¬C¼®MÁ…ä}ÉqÄE«J‹ŠêEçwñ0µ›¤ ¸£±›q^ã_ˉŒÝ°iŸ4Û'û\ÓÔŸ³œu(5[ÔÀîÝ®72\f*¸ “»ÙLAeë›ÊЉ·èý,ë}]Ò'%å1Îë‰Åoõ±´#ºßS/vYnàj7â`“DŒ¾Êr'^ÎÿÓD“â/›z4”0êÅ~F'ã7ò䛳êÌ<ó>høþŸWÖ«‡/ š'ãøDAè³tJµåwJq¤Æ½/ë÷\8OE»anä‘Ó’Ó"sXÖÞ+7H¦@U4ð‰þxXbgoà$P×Ê §¤Øi­Ò@—.v÷ ÚÖ¢!^Ð]ûR+ ¯G0}#8‘7Ÿ\SßËÂ,fáäl‡p-Ù4Zˆ©æXƒ‰úŽx%e†.ð4hÔMžÛë¡5‹¨\ñõEw`îyÿ¦•ó K7€ç ‰ñÒËéìâyÐ-¡‚'¿­€°™»¦Ýu„†C1Ýö´ØFv’3ñ£>- b¤Súkd¬Ó“œÉn †ÐIµÎsÇÖ0~DÚ%1yZ6/ Û£}Ë—zfM9Áq쳨¾ëî ¹Rb"¾Ê>Ã¥o¥Ô‰íVp+j…šimúÆQ‘µKƒ2‚À¯å'(@3v4ÝN£`3hšHšÁ´â*“8s]Ÿe…‚ µÍmI9K ôó¨n‰Æ¾Í‰)ø+Ú\”dÀyDKgûìpñAll] »^š±˜öµZÀ˜ï¤ÞŽòUÄéöO9ÕP噬Pöf¡åGé/çÐÅ'ó­ê|ë,ŽßœýºbU§<½²ÏÝ<àóXO—Ñ׆”˜[É I ˜°¸»ËÐÌÊÆŠâֿ产áuí6KÉwœæˆ))oñöÂV´ÜÈ0Ü8䤆²g²;¨Køõ d’£ãmswSUâÑh¢Ù¯+sÉQ}FM…ÇQ&ŠÂ,ãé­âÒ!4·UpÕç\E@xnyº‘\Òc ˆc_A‹S¨õ$= •mIJ(l è"b³›Í¾‘+ãÇ`»âQ|ßaØ¥Î÷q Û†Pm+·x«]¬,ß03t aœ-—9îÔv¦€2W¬á™Ä¼=ö[5Ô$o¬[ðuÛUòE,~ŸïI&o2È<7b­°óºÄÝTdÞ_oåI¹L3õ~Ô;Aï:¯ºUÔÄB‰æB{¨–žZÍó¶TºÔ§¬¡Ú²©I~™÷ØÛº‘'g£´Þ™ ÆR’%a8úX+Ü _ž§£7¿lž³<7*íèìgÑZ ÊÉÙ²§ˆošú¼m ÈŒ©@g÷w¥,x²BiìB e1€r¥…h>c´r Î@B¶0ûˆÑ™æÛè*ª)Æâb&â:É ÚÞ°Z: |æ­r–[ôæ„–´…ðYWòYW¿N)Ãw»AohÞ6» )?,çÒ3Žû»‹Ò‰«Šâd©[¡&w}žbœÞÑÕ\½J%-ø¿Ö®¥¹m# ß÷Wè– ‰ÂÄÑ–¹")›’·œÚTíaHŒˆñЂ ´Ô¯ßî@"ÁéA{k“ªø—5Æ<º¿þ^q[oЇLaÇ.:² prhM†ŒÛ{= Ð6)`íS]ÇÙÑSÕ·£+-ÏfOS“÷§k"ŠÑ*©-Åðü4&A²ŠY¤à­1o&üƒÇt[y(Z&KáFU. O›+Ç„j9çÍÏà*ÏY±„HŒÜ‹”ðØûÁ­Òà¢R=íŽ<’ˆµÝbtëÎ?Ma{2pzí çÑ›T”H×åÉД¨[:Ôõ‹Z;lI?6õz”+“.—`Å’,ë¼,LT†ªÌ~·Œ&‚çVnn³ë‰°µgš^.ï.âN.DHÀà<rSqÔÀ¢;ìû£wÆÉwRHåã#}k~¿¼¥'fË_'¦|²t„yÈâÎÈ粪Îìm!öTÍO¼ì·r’Èw®4k'kÏqTáÎ"ôW <|,WY:«v#ºJJf?ø]ÉnI’Ä’îávå Z)N2–°uðP…™ÀC÷:èÑ32mfÖ"ZdÍ" Ç@ⵑËq ÏX”¢Ø…íִбT"µ;ʬ±8ƒûƒ¿¯[dƒÑ•´¦ú™WÎ{“Û/—®b^LE«çñÅÔ]â£ÿ)q˜ÄKçCÿ˜žÖEêy;õ¬š79ÃTN£ÌY®ÍZˆ<±]<ÁC_›1^‹‡ôJWVù-T*´òP§ Þ´î‘ oôUÒm©RDY†¼-¤ ,˜f/N,·ó8 X̬ZlŽÞv;Y\>Ÿêc?UaûGoÌ®V.G#l‘Wí«8Z—­óñmžEp>¸j£¿Š°¿åÿYc§ |¯X‹ýÜ©ÞáêïÖ—8lq¥ß?swS‹Kõ$b‰ZöâU]¾ì_T¢<4@!MúCùQOå«ÔsµÍœ´Ü÷ÑA†•¶m.½·–¼ÁgiÌúÐg‹FÛÞSk¼ŸvÞgqFH]^„˱¾¬YœÞ§WÕT‚Q ¿Jé½ x³$¹+I¢Ú×i üÙ§Ûïg8èA Ç5÷쮽:aIo§˜Ëu{è\GÐf'r2a1ssݨ3ò°5fÝÙß…·rÍK¼3#jqwdžýÝI|¢–ƒ¿¸zÈáUŒYóÜnl«<9Õ¸(U×&kq9ؼ—æ§\--#?Ë9ýóÂ${Ò1š5²*ìC]£Ú¢]7Ö…Šm#÷ïòtg|×W5±VP±¸ú4òS†ô©›êè£ökÈóßìM7?{û^C}ò(Úr-7šhas·ÿXî?á³÷¨0ÉL«ø0Êâ$\å,˜^Tm“Ûixÿ©Œšç ªQЂÛIþÑòô,Ö-ÍàйR™òû˜Õc¥æu:)ÓîI-1JŽÞ‰fÐ=,`Ì B5ÀPÔ›C²X8·_IóÚGΓ2„Ùzb](BûC&–§M2ybŸ)V}öa‡Ø0 |’õ³¬WºyjØÊÄ9– -dîGœr]TJdv×’Z³'O„®“z#è@ŽÏm¿wLîµ+àòæPmg„PìdiÈ¢•¬µ £§pBM„S"‘/ª¾d]»×%ͼ¸D­O±¶¶›¢Å¾6`a‡rgíïHStí$½a€È~•ÃãØKƺhàŠ½×Tã…tiuŽN%P ð¬c+4Ú‚.7´@'\oïY )h‡÷èïKµ”觇O(V˃øN«ÕBFÈ fÇãF (0ÎsžÑа–úÅÕ<ßÑ·/cä Vh;dMyìgyÀ²²4Êh«^Ù˽µlNØ—Î+UÑùƃ‹Õ'#=6¬ö¸2ól§é%ú9ü›f¬àØJæv°÷24vÞÀ¦ÏÒ”(Û÷´Öëºãâê¶ ŸÛöELü¥'øÜj…6VP”Ìmïí*êr…ZäUÏ”žóÞ¶M ÏmHúM Uç:.è'ƒ4[q ؆ÍÔP`;ÉZ”Å„ú¬J¿Äf.¼+oå~ïÒ‹Dq†qÈÚ™k­óBG( :Q=—1Ïãø^<Ñ•êìÊ–Œ0 ÇûVš×b`%:Ð?ÊÓˆå‰ÿ$º¶Èc;È*Æ<"ž"†6°üÖÖ²Q$â¯{†¨)ðÓ•ÏóU݈½‚–ÏÛI¹¦@œÇNIè§=(çxC W·Ü’8À¯æY¾+ì]Ô*N|ž•€èØ1Þnªp8!<ãÔ,æ©B?a(’ãóMGøg,„[þ&*st—ÉáRá¢ÿîlI,§‡Å¶“<™È½s4:ZP ìÚW$âÝj2•£ÒŽÒ]e8§–†ÏzUÔ.‡®x¶•Ðà8ø1?H°ÿ¶2ñè§0ÎÚb¦ iÂÓ¤l2;K´ÐÚ>Ø¡UÅ Imæéú‡'ÏÞ×.ï¼Þ$L²(eeÚ´@zƒ­°Ãn/¢’MMn0ÏžÜÒ­¼½ƒý_"ïb(8ÑŸç=Š:㢃Vö"KðCƒ CïÒ)Èy' þ„€'i¡ÈXc<Ùâê‹Âøœ¡`Ç“˜Fðb°ÜXLLjÓ·jÓÂ9üiß™k‡úÎöߢ4ø7?c~µš³ÆßÚ!Þ{©à/Þ};ìÖ5rßk~s»c†uò•ZÞŸGšN9ÐÚܫ˲ÇQ¬i¸v÷0¯Þ^ª½ëba“1Ì_‹ã$ä✠~¨×Ó÷)ù¤¬æ‘²0x›¦Êì¨ð«B‰ú­>‰ÍŽË½÷ФÖx)ý<5óh1sw9^@ôgôÓ0ö}–kW[m…÷zÙk oÆ| ÞÕz€]ÿH–m†eB­Ïhq—3ûïÕ6*cu/hˆk<5¬‹SúŒ2ã;Þtw€ËãU‘ž¸™šK‹£õ¹8$â€Çi¿‚MøFe«âQ·LÂñjxm™ÉD-y/²"¿oádgçð8Ÿ š¤ÑÊ_Å,ó1øaPM†_„07\’~ÏÔתáµJwèì:‚ N›ÉKY\Ý©Æ8 ŒQ1®¶/˜Ql-y3—J˜'&QjfÛ~“[Çdb´Ÿù²Y’×eñ÷¶º¢Ží÷(?Ó¤—±„JF½ÓˆuyÞb¾]£Á&©ãœsùÝn?<½\ò QÆÒ¶ãHÙ»`}œâ…¨ò6•`Nv t´y£5$ÄcS:ÉX͹­Óã`u7‹%sèÖ¢ íÈS×¶k¯€Æ§eÞ ÖŽm>ÙN\"fS%CÎ Mn‚‘’œ ªú ¿_l·Š .nuØ{Ïâ°‘;Ö*?A­K»‹c…¾ )ÆÍoŠò8ÎW Ëel#+ ”Q´×Bjè´õJqj7“Ë»“$‘ }G½ïÚšÓ½-Wqšf žx‚’ÚëLòÕ1uízm þ2÷›/²«iß¿/¢›ó¦ 1 sÅÊ+h÷ð·%ûäåq’ñâ„%Ž4›ðOI>{ÆIŒqÖBX‘ûœ’ó©mĞ؋eÛõ šŒG2ÿGvO? S‘Ó‰&ã¥Å"þü‰‹¡»åÙÝi¶ t¬PŠמèàÿjº›]ûÊÜBeF›Š YÄ:ßÇ„‹«Í÷’¢ŸKá(Íü$…ÿ°{Ýzõ{„ŒuÑÏëm¼í:WøáëÁÆp2tjÑ¡ûÍ“¤l䞌eü{S`À‰˜˜&}V.)s×lâ'¬l[Q×èÊ­jÕwö޾³Ò¦´ø‚uLí=:Ó™¶ouÒPIìHW'p$Â޲ÀOVqÈ"z÷¥l‹¶“DDN­L eÈÞ_˪hÜʹ9˜+ ^BÃBoŒù¨« ó,ÊX4E¬XfjX,ãe“ó>wZjrð0iÈΙ7Û*ùåß¹ugUpÕ²V·}Ö:ûå#^Tq¢!uZ 8t¿\ü§37#ÿ_ÞMò§NBp}–‹ÇF\°á ¿­¤à^<¿ÉýÔR÷ Ö@Š ©2ü48ˆ.¯[—]œÀGËcλñâ&ëכ͡ªZجÞs=tô¤Eã`úzuÑÁ>òÓúF5ƒ#p±QÅ>K¤Pž! »þ uúw8ÁΣTû=œeªzÕþ‰stÓ8ðã—mongodb-1.1.5/tests/utils/basic-skipif.inc0000664000175000017500000000017412673034026020351 0ustar jmikolajmikola "", "STANDALONE_24" => "", "STANDALONE_26" => "", "STANDALONE_30" => "", "STANDALONE_SSL" => "", "STANDALONE_AUTH" => "", "STANDALONE_X509" => "", "STANDALONE_PLAIN" => "", "REPLICASET" => "", ); $servers = array_merge($servers, $config); def($servers); $consts = array( "DATABASE_NAME" => "phongo", "COLLECTION_NAME" => makeCollectionNameFromFilename($_SERVER["SCRIPT_FILENAME"]), ); def($consts); // These use values from constants defined above $consts = array( "NS" => DATABASE_NAME . "." . COLLECTION_NAME, ); def($consts); /* If its not defined, set it to what the MongoDB exts define it, since this is mostly used for pecl/bson testing */ if (!defined("BSON_NAMESPACE")) { define("BSON_NAMESPACE", "MongoDB\\BSON"); } mongodb-1.1.5/tests/utils/classes.inc0000664000175000017500000000275212673034026017446 0ustar jmikolajmikolaname = $name; $this->age = $age; $this->addresses = array(); $this->secret = "$name confidential info"; } function addAddress(Address $address) { $this->addresses[] = $address; } function addFriend(Person $friend) { $this->friends[] = $friend; } function bsonSerialize() { return array( "name" => $this->name, "age" => $this->age, "addresses" => $this->addresses, "friends" => $this->friends, ); } function bsonUnserialize(array $data) { $this->name = $data["name"]; $this->age = $data["age"]; $this->addresses = $data["addresses"]; $this->friends = $data["friends"]; } } class Address implements BSON\Persistable { protected $zip; protected $country; function __construct($zip, $country) { $this->zip = $zip; $this->country = $country; } function bsonSerialize() { return array( "zip" => $this->zip, "country" => $this->country, ); } function bsonUnserialize(array $data) { $this->zip = $data["zip"]; $this->country = $data["country"]; } } mongodb-1.1.5/tests/utils/tools.php0000664000175000017500000003067012673034026017167 0ustar jmikolajmikola= 0x20 && $i <= 0x7E) ? chr($i) : $pad; } } $hex = str_split(bin2hex($data), $width * 2); $chars = str_split(strtr($data, $from, $to), $width); $offset = 0; $length = $width * 3; foreach ($hex as $i => $line) { printf("%6X : %-{$length}s [%s]\n", $offset, implode(' ', str_split($line, 2)), $chars[$i]); $offset += $width; } } /** * Return a collection name to use for the test file. * * The filename will be stripped of the base path to the test suite (prefix) as * well as the PHP file extension (suffix). Special characters (including hyphen * for shell compatibility) will be replaced with underscores. * * @param string $filename * @return string */ function makeCollectionNameFromFilename($filename) { $filename = realpath($filename); $prefix = realpath(dirname(__FILE__) . '/..') . DIRECTORY_SEPARATOR; $replacements = array( // Strip test path prefix sprintf('/^%s/', preg_quote($prefix, '/')) => '', // Strip file extension suffix '/\.php$/' => '', // SKIPIFs add ".skip" between base name and extension '/\.skip$/' => '', // Replace special characters with underscores sprintf('/[%s]/', preg_quote('-$/\\', '/')) => '_', ); return preg_replace(array_keys($replacements), array_values($replacements), $filename); } function TESTCOMMANDS($uri) { $cmd = array( "configureFailPoint" => 1, ); $command = new MongoDB\Driver\Command($cmd); $manager = new MongoDB\Driver\Manager($uri); try { $result = $manager->executeCommand("test", $command); } catch(Exception $e) { /* command not found */ if ($e->getCode() == 59) { die("skip this test requires mongod with enableTestCommands"); } } } function NEEDS($uri) { if (!constant($uri)) { exit("skip -- need '$uri' defined"); } } function PREDICTABLE() { global $servers; foreach($servers as $k => $v) { if (!defined($k) || !constant($k)) { exit("skip - needs predictable environment (e.g. vagrant)\n"); } } } function SLOW() { if (getenv("SKIP_SLOW_TESTS")) { exit("skip SKIP_SLOW_TESTS"); } } function LOAD($uri, $dbname = DATABASE_NAME, $collname = COLLECTION_NAME, $filename = null) { if (!$filename) { $filename = "compress.zlib://" . __DIR__ . "/" . "PHONGO-FIXTURES.json.gz"; } $manager = new MongoDB\Driver\Manager($uri); $bulk = new MongoDB\Driver\BulkWrite(['ordered' => false]); $server = $manager->selectServer(new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_PRIMARY)); $data = file_get_contents($filename); $array = json_decode($data); foreach($array as $document) { $bulk->insert($document); } $retval = $server->executeBulkWrite("$dbname.$collname", $bulk); if ($retval->getInsertedCount() !== count($array)) { exit(sprintf('skip Fixtures were not loaded (expected: %d, actual: %d)', $total, $retval->getInsertedCount())); } } function CLEANUP($uri, $dbname = DATABASE_NAME, $collname = COLLECTION_NAME) { try { $manager = new MongoDB\Driver\Manager($uri); $cmd = new MongoDB\Driver\Command(array("drop" => $collname)); $rp = new MongoDB\Driver\ReadPreference(MongoDB\Driver\ReadPreference::RP_PRIMARY); try { $manager->executeCommand($dbname, $cmd, $rp); } catch(Exception $e) { do { /* ns not found */ if ($e->getCode() == 59 || $e->getCode() == 26) { continue; } throw $e; } while (0); } } catch(Exception $e) { echo "skip (cleanup); $uri: " . $e->getCode(), ": ", $e->getMessage(); exit(1); } } function START($id, array $options = array()) { /* starting/stopping servers only works using the Vagrant setup */ PREDICTABLE(); $options += array("name" => "mongod", "id" => $id); $opts = array( "http" => array( "timeout" => 60, "method" => "PUT", "header" => "Accept: application/json\r\n" . "Content-type: application/x-www-form-urlencoded", "content" => json_encode($options), "ignore_errors" => true, ), ); $ctx = stream_context_create($opts); $json = file_get_contents(getMOUri() . "/servers/$id", false, $ctx); $result = json_decode($json, true); /* Failed -- or was already started */ if (!isset($result["mongodb_uri"])) { DELETE($id); define($id, false); } else { define($id, $result["mongodb_uri"]); $FILENAME = sys_get_temp_dir() . "/PHONGO-SERVERS.json"; $json = file_get_contents($FILENAME); $config = json_decode($json, true); $config[$id] = constant($id); file_put_contents($FILENAME, json_encode($config, JSON_PRETTY_PRINT)); } } function DELETE($id) { $opts = array( "http" => array( "timeout" => 60, "method" => "DELETE", "header" => "Accept: application/json\r\n", "ignore_errors" => true, ), ); $ctx = stream_context_create($opts); $json = file_get_contents(getMOUri() . "/servers/$id", false, $ctx); $FILENAME = sys_get_temp_dir() . "/PHONGO-SERVERS.json"; $json = file_get_contents($FILENAME); $config = json_decode($json, true); unset($config[$id]); file_put_contents($FILENAME, json_encode($config, JSON_PRETTY_PRINT)); } function severityToString($type) { switch($type) { case E_WARNING: return "E_WARNING"; default: return "Some other #_$type"; } } function raises($function, $type, $infunction = null) { $errhandler = function($severity, $message, $file, $line, $errcontext) { throw new ErrorException($message, 0, $severity, $file, $line); }; set_error_handler($errhandler, $type); try { $function(); } catch(Exception $e) { if ($e instanceof ErrorException && $e->getSeverity() & $type) { if ($infunction) { $trace = $e->getTrace(); $function = $trace[0]["function"]; if (strcasecmp($function, $infunction) == 0) { printf("OK: Got %s thrown from %s\n", $exceptionname, $infunction); } else { printf("ALMOST: Got %s - but was thrown in %s, not %s\n", $exceptionname, $function, $infunction); } restore_error_handler(); return $e->getMessage(); } printf("OK: Got %s\n", severityToString($type)); } else { printf("ALMOST: Got %s - expected %s\n", get_class($e), $exceptionname); } restore_error_handler(); return $e->getMessage(); } echo "FAILED: Expected $exceptionname thrown!\n"; restore_error_handler(); } function throws($function, $exceptionname, $infunction = null) { try { $function(); } catch(Exception $e) { $message = str_replace(array("\n", "\r"), ' ', $e->getMessage()); if ($e instanceof $exceptionname) { if ($infunction) { $trace = $e->getTrace(); $function = $trace[0]["function"]; if (strcasecmp($function, $infunction) == 0) { printf("OK: Got %s thrown from %s\n", $exceptionname, $infunction); } else { printf("ALMOST: Got %s - but was thrown in %s, not %s (%s)\n", $exceptionname, $function, $infunction, $message); } return $e->getMessage(); } printf("OK: Got %s\n", $exceptionname); } else { printf("ALMOST: Got %s (%s) - expected %s\n", get_class($e), $message, $exceptionname); } return $e->getMessage(); } echo "FAILED: Expected $exceptionname thrown, but no exception thrown!\n"; } function printServer(MongoDB\Driver\Server $server) { printf("server: %s:%d\n", $server->getHost(), $server->getPort()); } function printWriteResult(MongoDB\Driver\WriteResult $result, $details = true) { printServer($result->getServer()); printf("insertedCount: %d\n", $result->getInsertedCount()); printf("matchedCount: %d\n", $result->getMatchedCount()); printf("modifiedCount: %d\n", $result->getModifiedCount()); printf("upsertedCount: %d\n", $result->getUpsertedCount()); printf("deletedCount: %d\n", $result->getDeletedCount()); foreach ($result->getUpsertedIds() as $index => $id) { printf("upsertedId[%d]: ", $index); var_dump($id); } $writeConcernError = $result->getWriteConcernError(); printWriteConcernError($writeConcernError ? $writeConcernError : null, $details); foreach ($result->getWriteErrors() as $writeError) { printWriteError($writeError); } } function printWriteConcernError(MongoDB\Driver\WriteConcernError $error = null, $details) { if ($error) { /* This stuff is generated by the server, no need for us to test it */ if (!$details) { printf("writeConcernError: %s (%d)\n", $error->getMessage(), $error->getCode()); return; } var_dump($error); printf("writeConcernError.message: %s\n", $error->getMessage()); printf("writeConcernError.code: %d\n", $error->getCode()); printf("writeConcernError.info: "); var_dump($error->getInfo()); } } function printWriteError(MongoDB\Driver\WriteError $error) { var_dump($error); printf("writeError[%d].message: %s\n", $error->getIndex(), $error->getMessage()); printf("writeError[%d].code: %d\n", $error->getIndex(), $error->getCode()); } function getInsertCount($retval) { return $retval->getInsertedCount(); } function getModifiedCount($retval) { return $retval->getModifiedCount(); } function getDeletedCount($retval) { return $retval->getDeletedCount(); } function getUpsertedCount($retval) { return $retval->getUpsertedCount(); } function getWriteErrors($retval) { return (array)$retval->getWriteErrors(); } function def($arr) { foreach($arr as $const => $value) { define($const, getenv("PHONGO_TEST_$const") ?: $value); } } function configureFailPoint(MongoDB\Driver\Manager $manager, $failPoint, $mode, $data = array()) { $doc = array( "configureFailPoint" => $failPoint, "mode" => $mode, ); if ($data) { $doc["data"] = $data; } $cmd = new MongoDB\Driver\Command($doc); $result = $manager->executeCommand("admin", $cmd); $arr = current($result->toArray()); if (empty($arr->ok)) { var_dump($result); throw new RuntimeException("Failpoint failed"); } return true; } function failMaxTimeMS(MongoDB\Driver\Manager $manager) { return configureFailPoint($manager, "maxTimeAlwaysTimeOut", array("times" => 1)); } function getMOUri() { if (!($HOST = getenv("MONGODB_ORCHESTRATION_HOST"))) { $HOST = "192.168.112.10"; } if (!($PORT = getenv("MONGODB_ORCHESTRATION_PORT"))) { $PORT = "8889"; } $MO = "http://$HOST:$PORT/v1"; return $MO; } function getMOPresetBase() { if (!($BASE = getenv("mongodb_orchestration_base"))) { $BASE = "/phongo/"; } return $BASE; } function toPHP($var, $typemap = array()) { $func = BSON_NAMESPACE . "\\" . __FUNCTION__; return $func($var, $typemap); } function fromPHP($var) { $func = BSON_NAMESPACE . "\\" . __FUNCTION__; return $func($var); } function toJSON($var) { $func = BSON_NAMESPACE . "\\" . __FUNCTION__; return $func($var); } function fromJSON($var) { $func = BSON_NAMESPACE . "\\" . __FUNCTION__; return $func($var); } /* Note: this fail point may terminate the mongod process, so you may want to * use this in conjunction with a throwaway server. */ function failGetMore(MongoDB\Driver\Manager $manager) { return configureFailPoint($manager, "failReceivedGetmore", "alwaysOn"); } mongodb-1.1.5/tests/writeConcern/writeconcern-constants.phpt0000664000175000017500000000045512673034026024227 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteConcern constants --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- string(8) "majority" ===DONE=== mongodb-1.1.5/tests/writeConcern/writeconcern-ctor-001.phpt0000664000175000017500000000433012673034026023454 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteConcern construction --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> string(8) "majority" ["wmajority"]=> bool(true) ["wtimeout"]=> int(0) ["journal"]=> NULL } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> string(8) "majority" ["wmajority"]=> bool(true) ["wtimeout"]=> int(1000) ["journal"]=> NULL } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> int(2) ["wmajority"]=> bool(false) ["wtimeout"]=> int(0) ["journal"]=> NULL } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> int(2) ["wmajority"]=> bool(false) ["wtimeout"]=> int(2000) ["journal"]=> NULL } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> string(7) "tagname" ["wmajority"]=> bool(false) ["wtimeout"]=> int(0) ["journal"]=> NULL } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> string(6) "string" ["wmajority"]=> bool(false) ["wtimeout"]=> int(3000) ["journal"]=> NULL } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> string(6) "string" ["wmajority"]=> bool(false) ["wtimeout"]=> int(4000) ["journal"]=> bool(true) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> string(6) "string" ["wmajority"]=> bool(false) ["wtimeout"]=> int(5000) ["journal"]=> bool(false) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> string(6) "string" ["wmajority"]=> bool(false) ["wtimeout"]=> int(6000) ["journal"]=> NULL } ===DONE=== mongodb-1.1.5/tests/writeConcern/writeconcern-ctor_error-001.phpt0000664000175000017500000000122312673034026024663 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteConcern construction (invalid arguments) --SKIPIF-- --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException MongoDB\Driver\WriteConcern::__construct() expects at most 3 parameters, 4 given ===DONE=== mongodb-1.1.5/tests/writeConcern/writeconcern-ctor_error-002.phpt0000664000175000017500000000206312673034026024667 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteConcern construction (invalid w type) --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected w to be integer or string, %r(double|float)%r given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected w to be integer or string, boolean given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected w to be integer or string, array given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected w to be integer or string, object given OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected w to be integer or string, %r(null|NULL)%r given ===DONE=== mongodb-1.1.5/tests/writeConcern/writeconcern-ctor_error-003.phpt0000664000175000017500000000073112673034026024670 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteConcern construction (invalid w range) --SKIPIF-- --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected w to be >= -3, -4 given ===DONE=== mongodb-1.1.5/tests/writeConcern/writeconcern-ctor_error-004.phpt0000664000175000017500000000075112673034026024673 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteConcern construction (invalid wtimeout range) --SKIPIF-- --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected wtimeout to be >= 0, -1 given ===DONE=== mongodb-1.1.5/tests/writeConcern/writeconcern-ctor_error-005.phpt0000664000175000017500000000111512673034026024667 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteConcern construction (invalid wtimeout range) --SKIPIF-- --FILE-- ===DONE=== --EXPECT-- OK: Got MongoDB\Driver\Exception\InvalidArgumentException Expected wtimeout to be <= 2147483647, 2147483648 given ===DONE=== mongodb-1.1.5/tests/writeConcern/writeconcern-debug-001.phpt0000664000175000017500000000132612673034026023575 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteConcern debug output should include all fields for w default --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> NULL ["wmajority"]=> bool(false) ["wtimeout"]=> int(1000) ["journal"]=> bool(true) } ===DONE=== mongodb-1.1.5/tests/writeConcern/writeconcern-debug-002.phpt0000664000175000017500000000163012673034026023574 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteConcern debug output --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> int(1) ["wmajority"]=> bool(false) ["wtimeout"]=> int(0) ["journal"]=> NULL } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> string(3) "tag" ["wmajority"]=> bool(false) ["wtimeout"]=> int(1000) ["journal"]=> bool(false) } object(MongoDB\Driver\WriteConcern)#%d (%d) { ["w"]=> string(8) "majority" ["wmajority"]=> bool(true) ["wtimeout"]=> int(500) ["journal"]=> bool(true) } ===DONE=== mongodb-1.1.5/tests/writeConcern/writeconcern-getjournal-001.phpt0000664000175000017500000000110012673034026024647 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteConcern::getJournal() --SKIPIF-- --FILE-- getJournal()); } // Test with default value $wc = new MongoDB\Driver\WriteConcern(1, 0); var_dump($wc->getJournal()); ?> ===DONE=== --EXPECT-- bool(true) bool(false) bool(true) bool(false) NULL NULL ===DONE=== mongodb-1.1.5/tests/writeConcern/writeconcern-getw-001.phpt0000664000175000017500000000107112673034026023452 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteConcern::getW() --SKIPIF-- --FILE-- getW()); } ?> ===DONE=== --EXPECT-- string(8) "majority" string(8) "majority" NULL int(-1) int(0) int(1) int(2) string(3) "tag" string(1) "2" ===DONE=== mongodb-1.1.5/tests/writeConcern/writeconcern-getwtimeout-001.phpt0000664000175000017500000000077312673034026025071 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteConcern::getWtimeout() --SKIPIF-- --FILE-- getWtimeout()); } // Test with default value $wc = new MongoDB\Driver\WriteConcern(1); var_dump($wc->getWtimeout()); ?> ===DONE=== --EXPECT-- int(0) int(1) int(0) ===DONE=== mongodb-1.1.5/tests/writeConcern/writeconcern_error-001.phpt0000664000175000017500000000062312673034026023721 0ustar jmikolajmikola--TEST-- MongoDB\Driver\WriteConcern cannot be extended --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- Fatal error: Class MyWriteConcern may not inherit from final class (MongoDB\Driver\WriteConcern) in %s on line %d mongodb-1.1.5/win32/bson-config.h0000664000175000017500000000276712673034026016341 0ustar jmikolajmikola#ifndef BSON_CONFIG_H #define BSON_CONFIG_H /* * Define to 1234 for Little Endian, 4321 for Big Endian. */ #define BSON_BYTE_ORDER 1234 /* * Define to 1 if you have stdbool.h */ #define BSON_HAVE_STDBOOL_H 0 #if BSON_HAVE_STDBOOL_H != 1 # undef BSON_HAVE_STDBOOL_H #endif /* * Define to 1 for POSIX-like systems, 2 for Windows. */ #define BSON_OS 2 /* * Define to 1 if we have access to GCC 64-bit atomic builtins. * While this requires GCC 4.1+ in most cases, it is also architecture * dependent. For example, some PPC or ARM systems may not have it even * if it is a recent GCC version. */ #define BSON_HAVE_ATOMIC_64_ADD_AND_FETCH 0 #if BSON_HAVE_ATOMIC_64_ADD_AND_FETCH != 1 # undef BSON_HAVE_ATOMIC_64_ADD_AND_FETCH #endif /* * Define to 1 if your system requires {} around PTHREAD_ONCE_INIT. * This is typically just Solaris 8-10. */ #define BSON_PTHREAD_ONCE_INIT_NEEDS_BRACES 0 #if BSON_PTHREAD_ONCE_INIT_NEEDS_BRACES != 1 # undef BSON_PTHREAD_ONCE_INIT_NEEDS_BRACES #endif /* * Define to 1 if you have clock_gettime() available. */ #define BSON_HAVE_CLOCK_GETTIME 0 #if BSON_HAVE_CLOCK_GETTIME != 1 # undef BSON_HAVE_CLOCK_GETTIME #endif /* * Define to 1 if you have strnlen available on your platform. */ #define BSON_HAVE_STRNLEN 0 #if BSON_HAVE_STRNLEN != 1 # undef BSON_HAVE_STRNLEN #endif /* * Define to 1 if you have snprintf available on your platform. */ #define BSON_HAVE_SNPRINTF 0 #if BSON_HAVE_SNPRINTF != 1 # undef BSON_HAVE_SNPRINTF #endif #endif /* BSON_CONFIG_H */ mongodb-1.1.5/win32/bson-version.h0000664000175000017500000000515712673034026016555 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if !defined (BSON_INSIDE) && !defined (BSON_COMPILATION) #error "Only can be included directly." #endif #ifndef BSON_VERSION_H #define BSON_VERSION_H /** * BSON_MAJOR_VERSION: * * BSON major version component (e.g. 1 if %BSON_VERSION is 1.2.3) */ #define BSON_MAJOR_VERSION (1) /** * BSON_MINOR_VERSION: * * BSON minor version component (e.g. 2 if %BSON_VERSION is 1.2.3) */ #define BSON_MINOR_VERSION (1) /** * BSON_MICRO_VERSION: * * BSON micro version component (e.g. 3 if %BSON_VERSION is 1.2.3) */ #define BSON_MICRO_VERSION (3) /** * BSON_VERSION: * * BSON version. */ #define BSON_VERSION (1.1.3) /** * BSON_VERSION_S: * * BSON version, encoded as a string, useful for printing and * concatenation. */ #define BSON_VERSION_S "1.1.3" /** * BSON_VERSION_HEX: * * BSON version, encoded as an hexadecimal number, useful for * integer comparisons. */ #define BSON_VERSION_HEX (BSON_MAJOR_VERSION << 24 | \ BSON_MINOR_VERSION << 16 | \ BSON_MICRO_VERSION << 8) /** * BSON_CHECK_VERSION: * @major: required major version * @minor: required minor version * @micro: required micro version * * Compile-time version checking. Evaluates to %TRUE if the version * of BSON is greater than the required one. */ #define BSON_CHECK_VERSION(major,minor,micro) \ (BSON_MAJOR_VERSION > (major) || \ (BSON_MAJOR_VERSION == (major) && BSON_MINOR_VERSION > (minor)) || \ (BSON_MAJOR_VERSION == (major) && BSON_MINOR_VERSION == (minor) && \ BSON_MICRO_VERSION >= (micro))) /** * bson_get_major_version: * * Helper function to return the runtime major version of the library. */ int bson_get_major_version (void); /** * bson_get_minor_version: * * Helper function to return the runtime minor version of the library. */ int bson_get_minor_version (void); /** * bson_get_micro_version: * * Helper function to return the runtime micro version of the library. */ int bson_get_micro_version (void); #endif /* BSON_VERSION_H */ mongodb-1.1.5/win32/mongoc-config.h0000664000175000017500000000205612673034026016651 0ustar jmikolajmikola/* * Copyright 2013 MongoDB Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MONGOC_CONFIG_H #define MONGOC_CONFIG_H /* * MONGOC_ENABLE_SSL is set from configure to determine if we are * compiled with SSL support. */ #define MONGOC_ENABLE_SSL 1 #if MONGOC_ENABLE_SSL != 1 # undef MONGOC_ENABLE_SSL #endif /* * MONGOC_ENABLE_SASL is set from configure to determine if we are * compiled with SASL support. */ #define MONGOC_ENABLE_SASL 1 #if MONGOC_ENABLE_SASL != 1 # undef MONGOC_ENABLE_SASL #endif #endif /* MONGOC_CONFIG_H */ mongodb-1.1.5/win32/mongoc-version.h0000664000175000017500000000440712673034026017073 0ustar jmikolajmikola/* * Copyright 2013 MongoDB, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if !defined (MONGOC_INSIDE) && !defined (MONGOC_COMPILATION) #error "Only can be included directly." #endif #ifndef MONGOC_VERSION_H #define MONGOC_VERSION_H /** * MONGOC_MAJOR_VERSION: * * MONGOC major version component (e.g. 1 if %MONGOC_VERSION is 1.2.3) */ #define MONGOC_MAJOR_VERSION (1) /** * MONGOC_MINOR_VERSION: * * MONGOC minor version component (e.g. 2 if %MONGOC_VERSION is 1.2.3) */ #define MONGOC_MINOR_VERSION (1) /** * MONGOC_MICRO_VERSION: * * MONGOC micro version component (e.g. 3 if %MONGOC_VERSION is 1.2.3) */ #define MONGOC_MICRO_VERSION (2) /** * MONGOC_VERSION: * * MONGOC version. */ #define MONGOC_VERSION (1.1.2) /** * MONGOC_VERSION_S: * * MONGOC version, encoded as a string, useful for printing and * concatenation. */ #define MONGOC_VERSION_S "1.1.2" /** * MONGOC_VERSION_HEX: * * MONGOC version, encoded as an hexadecimal number, useful for * integer comparisons. */ #define MONGOC_VERSION_HEX (MONGOC_MAJOR_VERSION << 24 | \ MONGOC_MINOR_VERSION << 16 | \ MONGOC_MICRO_VERSION << 8) /** * MONGOC_CHECK_VERSION: * @major: required major version * @minor: required minor version * @micro: required micro version * * Compile-time version checking. Evaluates to %TRUE if the version * of MONGOC is greater than the required one. */ #define MONGOC_CHECK_VERSION(major,minor,micro) \ (MONGOC_MAJOR_VERSION > (major) || \ (MONGOC_MAJOR_VERSION == (major) && MONGOC_MINOR_VERSION > (minor)) || \ (MONGOC_MAJOR_VERSION == (major) && MONGOC_MINOR_VERSION == (minor) && \ MONGOC_MICRO_VERSION >= (micro))) #endif /* MONGOC_VERSION_H */ mongodb-1.1.5/ChangeLog0000664000175000017500000042263112673034026014570 0ustar jmikolajmikola2016-03-18 Jeremy Mikola * Merge pull request #266 2016-03-18 Jeremy Mikola * PHPC-632: Define MONGOC_NO_AUTOMATIC_GLOBALS when bundling libmongoc 2016-03-10 Jeremy Mikola * Back to -dev 2016-03-10 Jeremy Mikola * Add 1.1.4 release notes 2016-03-10 Jeremy Mikola * Bump extension version to 1.1.4 2016-03-10 Jeremy Mikola * Merge pull request #260 2016-03-09 Jeremy Mikola * PHPC-620: Lowercase hexadecimal strings in ObjectID ctor 2016-03-09 Jeremy Mikola * Fix test title 2016-03-10 Jeremy Mikola * Merge pull request #259 2016-03-09 Jeremy Mikola * PHPC-623: Fix 64-bit integer conversion for BSON keys 2016-03-04 Jeremy Mikola * Back to -dev 2016-03-04 Jeremy Mikola * Add 1.1.3 release notes 2016-03-04 Jeremy Mikola * Bump extension version to 1.1.3 2016-03-04 Jeremy Mikola * Merge pull request #252 2016-03-03 Jeremy Mikola * Skip PHPC-545 test on HHVM due to __pclass encoding order 2016-03-04 Jeremy Mikola * Merge pull request #249 2016-03-02 Jeremy Mikola * Improve comment in bson-toJSON_error-001.phpt 2016-03-02 Jeremy Mikola * PHPC-613: toJSON() should throw if bson_as_json() fails 2016-03-02 Jeremy Mikola * PHPC-615: Return after throwing for bson_reader_read() error 2016-03-04 Jeremy Mikola * Merge pull request #250 2016-03-02 Jeremy Mikola * PHPC-616: Document and array visitors should throw for corrupt BSON 2016-03-02 Jeremy Mikola * PHPC-531: Fix double free in corrupt BSON visitor 2016-03-02 Jeremy Mikola * toPHP() regression tests for bson_reader_read() errors 2016-03-02 Jeremy Mikola * Merge pull request #248 2016-03-02 Jeremy Mikola * Prevent duplication and reduce strlen() usage 2016-03-01 Derick Rethans * Fixed PHPC-506: Use more descriptive messages in WriteExceptions 2016-02-29 Jeremy Mikola * Merge pull request #242 2016-02-25 Jeremy Mikola * PHPC-414: Combine 32-bit and 64-bit UTCDateTime debug handler tests 2016-02-29 Jeremy Mikola * Merge pull request #243 2016-02-26 Jeremy Mikola * PHPC-593: Binary type is an unsigned 8-bit integer 2016-02-26 Jeremy Mikola * PHPC-594: Timestamp components are unsigned 32-bit integers 2016-02-26 Jeremy Mikola * PHPC-595: Throw exception if wtimeout > INT32_MAX 2016-02-29 Jeremy Mikola * Merge pull request #241 2016-02-25 Jeremy Mikola * Use INT32 limit constants instead of INT/LONG 2016-02-25 Jeremy Mikola * PHPC-544: Use phongo_long in UTCDateTime ctor 2016-02-25 Jeremy Mikola * PHPC-544: Consult SIZEOF_ZEND_LONG for 64-bit integer support 2016-02-25 Jeremy Mikola * Remove unused macro, which is already defined in libbson 2016-02-25 Jeremy Mikola * PHPC-592: ADD_ASSOC_STRINGL() can only be used with string literals 2016-02-29 Jeremy Mikola * Revert "Merge pull request #241" 2016-02-29 Jeremy Mikola * Merge pull request #241 2016-02-24 Jeremy Mikola * wip 2016-02-24 Jeremy Mikola * Fix whitespace 2016-02-22 Jeremy Mikola * Fix BulkWrite::update() "multi" option usage in docs 2016-02-22 Jeremy Mikola * Merge pull request #226 2016-02-12 Jeremy Mikola * PHPC-545: Regression test for Peristable bug report 2016-02-09 Jeremy Mikola * PHPC-550: Always encode ODS field when serializing Persistable documents 2016-02-09 Jeremy Mikola * Regression test for executing BulkWrite multiple times 2016-02-10 Jeremy Mikola * Fix test title 2016-02-10 Jeremy Mikola * Tests should use and cleanup their own collection 2016-02-15 Jeremy Mikola * Merge pull request #231 2016-02-12 Jeremy Mikola * PHPC-581: Use ConnectionTimeoutException for server selection failures 2016-02-15 Jeremy Mikola * Merge pull request #232 2016-02-12 Jeremy Mikola * PHPC-582: Manager::selectServer() should select exception class based on bson_error_t 2016-02-15 Jeremy Mikola * Merge pull request #221 2016-02-12 Jeremy Mikola * PHPC-553: Relax expected output patterns for HHVM 2016-02-12 Jeremy Mikola * PHPC-553: Check for connection exceptions in exec and SS methods 2016-02-04 Jeremy Mikola * PHPC-553: Suppress warnings during stream creation 2016-02-15 Jeremy Mikola * Merge pull request #233 2016-02-12 Jeremy Mikola * PHPC-566: Remove request_id from Manager::__debugInfo() 2016-02-15 Jeremy Mikola * Merge pull request #234 2016-02-12 Jeremy Mikola * PHPC-567: Bump config.m4 library deps 2016-02-12 Jeremy Mikola * PHPC-567: Upgrade libbson and libmongoc to 1.3.3 2016-02-12 Jeremy Mikola * Merge pull request #230 2016-02-12 Derick Rethans * Skip this test on HHVM, as its DateTime class is ancient and behaves differently 2016-02-11 Jeremy Mikola * Merge pull request #227 2016-02-10 Jeremy Mikola * PHPC-523: Parse readconcernlevel in URI options array 2016-02-11 Jeremy Mikola * Merge pull request #228 2016-02-10 Jeremy Mikola * PHPC-563: Remove undocumented Manager "hosts" URI option 2016-02-10 Jeremy Mikola * Merge pull request #218 2016-02-02 Jeremy Mikola * PHPC-539: Include read concern in Query debug output 2016-02-10 Jeremy Mikola * Merge pull request #225 2016-02-09 Jeremy Mikola * Regression test for extending final classes 2016-02-09 Jeremy Mikola * PHPC-519: Add missing modifiers to final class methods 2016-02-08 Jeremy Mikola * Merge pull request #223 2016-02-08 Jeremy Mikola * PHPC-538: ObjectID should not abort on null ctor arg 2016-02-03 Jeremy Mikola * Merge pull request #217 2016-02-02 Jeremy Mikola * PHPC-515: Test that negative cursor limits return one batch 2016-02-03 Derick Rethans * Merged pull request #206 2016-01-20 Derick Rethans * Fixed PHPC-543: MongoDB\BSON\UTCDateTime on 32 bit platforms parse argument wrong 2016-02-02 Jeremy Mikola * Merge pull request #216 2016-02-02 Derick Rethans * Fixed PHPC-558: Upgrade libmongoc and libbson to 1.3.2 2016-02-02 Jeremy Mikola * Remove Manager::executeInsert() usage in ODS docs 2016-01-12 Jeremy Mikola * Merge pull request #202 2016-01-12 Derick Rethans * Skip and fix test for HHVM with ReadConcerns 2016-01-07 Jeremy Mikola * Back to -dev 2016-01-07 Jeremy Mikola * Add 1.1.2 release notes 2016-01-07 Jeremy Mikola * Bump extension version to 1.1.2 2016-01-07 Jeremy Mikola * Merge pull request #196 2016-01-06 Jeremy Mikola * PHPC-496: Revert "Temporary workaround for warning in mongoc" 2016-01-07 Jeremy Mikola * Merge pull request #197 2016-01-06 Jeremy Mikola * Improve other config.m4 check messages 2015-12-31 Lior Kaplan * PHPC-534: Enable configure without SASL and support --with-mongodb-sasl=no 2015-12-31 Lior Kaplan * Improve SASL check message 2015-12-31 Lior Kaplan * Don't print pcre-dir usage during configure check 2016-01-06 Jeremy Mikola * Merge pull request #194 2016-01-01 Jeremy Mikola * PHPC-529: Prefix BSON functions to avoid symbol conflicts 2016-01-05 Jeremy Mikola * Merge pull request #192 2015-12-30 Jeremy Mikola * phongo_bson_append() can be static and get zval type internally 2015-12-30 Jeremy Mikola * PHPC-528: Support zval references when appending BSON 2015-12-30 Jeremy Mikola * Merge pull request #191 2015-12-30 Remi Collet * PHPC-527: fix call to add_index_stringl 2015-12-30 Jeremy Mikola * Merge pull request #185 2015-12-26 Remi Collet * PHPC-527: Fix PHP 7 / 32bits build 2015-12-22 Jeremy Mikola * Back to -dev 2015-12-22 Jeremy Mikola * Add 1.1.1 release notes 2015-12-22 Jeremy Mikola * Encode special characters in commit messages for package.xml 2015-12-22 Jeremy Mikola * Bump extension version to 1.1.1 2015-12-22 Jeremy Mikola * PHPC-285: Allow for PHP 7.x support in package.xml 2015-12-22 Jeremy Mikola * Merge pull request #172 2015-12-16 Jeremy Mikola * Fix protos for ReadPreference and WriteConcern 2015-12-22 Jeremy Mikola * Merge pull request #180 2015-12-22 Kanin Peanviriyakulkit * Remove "beta" in doc. 2015-12-22 Jeremy Mikola * Merge pull request #179 2015-12-21 Jeremy Mikola * PHPC-285: VC14 needs timezone defined for SSL function 2015-12-21 Jeremy Mikola * PHPC-285: Fix syntax for empty struct initializer 2015-12-18 Derick Rethans * Merged pull request #175 2015-12-18 Derick Rethans * Fixed test case, where PHP 5 and PHP 7 call the type differently 2015-12-18 Derick Rethans * Fixed 'dump on uninitialised value' with BSON deserialisation 2015-12-16 Derick Rethans * Fixed issues with PHP 7 and the new ReadConcern 2015-12-18 Derick Rethans * Fixed CS from Joe's patch 2015-12-14 Joe Watkins * fix leaks and logical errors for PHP 7 2015-11-07 Jeremy Mikola * PHPC-400: Compare WriteConcern journal arg with IS_TRUE 2015-11-07 Jeremy Mikola * PHPC-405: Additional zval* to zval changes 2015-11-07 Jeremy Mikola * PHPC-397: Additional RETURN_STRING updates 2015-11-07 Jeremy Mikola * PHPC-393: Don't BSON-encode non-public properties in PHP 7 2015-11-07 Jeremy Mikola * PHPC-390: Fix OnUpdateString calls within OnUpdateDebug 2015-11-07 Jeremy Mikola * PHPC-373: Additional MAKE_STD_ZVAL() cleanup 2015-11-07 Jeremy Mikola * PHPC-374: zend_string updates for OnUpdateDebug 2015-11-07 Jeremy Mikola * PHPC-404: Additional hash API changes 2015-11-07 Jeremy Mikola * PHPC-370: Additionally return_value_ptr and return_value_used suppressions 2015-11-07 Jeremy Mikola * PHPC-369: Additional Z__OBJ_P() macros 2015-11-07 Jeremy Mikola * PHPC-399: Additional zval_used_for_init cleanup 2015-09-24 Hannes Magnusson * PHPC-431: Add the testcase from the report 2015-09-24 Hannes Magnusson * PHPC-431: Segfault when using Manager through singleton class 2015-09-02 Hannes Magnusson * Use ZVAL_COPY_VALUE() 2015-09-01 Hannes Magnusson * Enable PHP7 on Travis 2015-09-01 Hannes Magnusson * PHPC-391 & PHPC-389: Stream and SSL API changes 2015-09-01 Hannes Magnusson * PHPC-387: Properly init the iterator, and don't free it on dtor 2015-09-01 Hannes Magnusson * _id doesn't have to be object 2015-09-01 Hannes Magnusson * Fix incorrect version checks 2015-09-01 Hannes Magnusson * PHPC-405: zval drop a level; zval*->zval, zval**->zval* 2015-09-01 Hannes Magnusson * PHPC-404: off-by-one hash api changes 2015-09-01 Hannes Magnusson * PHPC-390: php.ini updates 2015-08-31 Hannes Magnusson * littlebit to eager on the zend_string, this is PHP5 2015-08-31 Hannes Magnusson * Get the zend_string value 2015-08-31 Hannes Magnusson * hash API changes, off-by-ones 2015-08-31 Hannes Magnusson * PHPC-380: Use the compatability macros to get the object 2015-08-31 Hannes Magnusson * Properly initialize the zval* we are working with 2015-08-31 Hannes Magnusson * +1 in PHP5, not PHP7 2015-08-31 Hannes Magnusson * Include numeric keys as well 2015-09-01 Patrick Boyd * Object property names missing due to lack of key length 2015-08-31 Hannes Magnusson * Should all compile now! 2015-08-31 Hannes Magnusson * Simpilfy iterating over a zval 2015-08-31 Hannes Magnusson * Use Z_ISUNDEF() to check the zval 2015-08-31 Hannes Magnusson * WS 2015-08-31 Patrick Boyd * PHPC-400: Handle IS_TRUE and IS_FALSE 2015-08-31 Hannes Magnusson * Simplify IS_ARRAY/IS_OBJECT discovery for PHP7 2015-08-31 Hannes Magnusson * PHPC-373: MAKE_STD_ZVAL() and zval* -> zval upgrades 2015-08-31 Hannes Magnusson * We already know the length 2015-08-31 Patrick Boyd * str_efree() not defined in PHP7 2015-08-31 Hannes Magnusson * PHPC-397: RETURN_*() should RETURN ! :) 2015-08-31 Hannes Magnusson * PHPC-399: zval_used_for_init is no longer needed (or defined) 2015-08-31 Hannes Magnusson * PHPC-398: zend_parse_parameter 's' expects a char* and size_t now 2015-08-28 Patrick Boyd * PHP7 upgrades 2015-08-31 Hannes Magnusson * PHPC-373: MAKE_STD_ZVAL() is gone 2015-08-31 Hannes Magnusson * PHPC-397: RETURN_STRING() duplicate argument removed 2015-08-31 Hannes Magnusson * PHPC-387: get_current_data() API changes 2015-08-31 Hannes Magnusson * PHPC-397: dup argument in most string macros removed 2015-08-31 Patrick Boyd * PHPC-380: Use our bc type for free_object argument 2015-08-31 Hannes Magnusson * PHPC-397: dup argument in most string macros removed 2015-08-31 Patrick Boyd * PHPC-396: HashTable no longer contains nApplyCount 2015-08-27 Patrick Boyd * PHPC-394: Fix issue with WriteException and zend_read_property 2015-08-31 Hannes Magnusson * PHPC-380: PHP7 create/free object changes 2015-08-27 Patrick Boyd * PHPC-380: create/free object handlers for PHP7 2015-08-27 Hannes Magnusson * Define the TODOs for PHP5, these are PHP7 TODOs 2015-08-27 Hannes Magnusson * PHPC-385: Remove leftover braces 2015-08-27 Hannes Magnusson * Sprinkle TODOs -- it compiles now! 2015-08-27 Hannes Magnusson * PHPC-374: php_stream_xport_create() now wants zend_string 2015-08-27 Hannes Magnusson * PHPC-388 - dtor on bson_to_zval() failure 2015-08-27 Hannes Magnusson * PHPC-387: Iterator API changes 2015-08-27 Hannes Magnusson * PHPC-386: Forward port Z_PHPDATE_P() to get php_date_obj 2015-08-27 Hannes Magnusson * PHPC-385: add_assoc_string_ex() doesn't have a duplicate param in PHP7 2015-08-27 Hannes Magnusson * PHPC-384: php_stream's no longer have resource ids 2015-08-27 Hannes Magnusson * PHPC-383: Simplify getting the current exception zval* 2015-08-26 Hannes Magnusson * PHPC-376: Cursor var_dump() is weird 2015-08-25 Hannes Magnusson * PHPC-373: Remove MAKE_STD_ZVAL() usage 2015-08-25 Hannes Magnusson * PHPC-374: zend_string* vs char* PHP API changes (1/many) 2015-08-25 Hannes Magnusson * PHPC-375: TSRMLS_FETCH_FROM_CTX() not applicable in PHP7 2015-08-25 Hannes Magnusson * PHPC-372: zend_throw_exception() return value changes 2015-08-25 Hannes Magnusson * PHP7: Start a phongo_compat.c with things that shouldn't be done in headers 2015-08-25 Hannes Magnusson * PHP7: Lets start with just php_phongo.c for now 2015-08-24 Hannes Magnusson * PHPC-371: Prep for PHP7 resource changes 2015-08-24 Hannes Magnusson * PHPC-370: Hardcode return_value_used to 1 in PHP7 2015-08-24 Hannes Magnusson * PHPC-370: return_value_ptr and return_value_used removed in PHP7 2015-08-24 Hannes Magnusson * PHPC-369: Use the new Z__OBJ_P() macros 2015-08-24 Hannes Magnusson * PHPC-369: Split PHP5 and PHP7 style custom object struct declrations 2015-08-24 Hannes Magnusson * PHPC-368: Refactor MongoDB\Driver\Manager ctor 2015-08-24 Hannes Magnusson * Fix const casting warning in php_array_api 2015-08-24 Hannes Magnusson * Resync with GitHub: https://github.com/sgolemon/php-array-api 2015-12-15 Jeremy Mikola * Back to -dev 2015-12-15 Jeremy Mikola * Include libbson and libmongoc version files in PECL package 2015-12-15 Jeremy Mikola * Add 1.1.0 release notes 2015-12-15 Jeremy Mikola * Bump extension version to 1.1.0 2015-12-14 Jeremy Mikola * Merge pull request #168 2015-12-14 Jeremy Mikola * PHPC-509: Default Manager URI to "mongodb://localhost:27017/" 2015-12-14 Jeremy Mikola * Merge pull request #167 2015-12-14 Jeremy Mikola * PHPC-448: Fix arginfo for ReadConcern constructor 2015-12-14 Jeremy Mikola * Merge pull request #163 2015-12-12 Jorgen Evens * PHPC-514: Fix --with-mongodb-sasl flag 2015-12-14 Jeremy Mikola * Merge pull request #166 2015-12-14 Hannes Magnusson * PHPC-512: Disable async stream connections 2015-12-14 Jeremy Mikola * Merge pull request #165 2015-12-14 Jeremy Mikola * PHPC-508: Construct valid stream URI for IPv6 literals 2015-12-11 Jeremy Mikola * Merge pull request #158 2015-12-10 Jeremy Mikola * PHPC-448: Manager::getReadConcern() and URI test 2015-12-10 Jeremy Mikola * PHPC-448: Support readConcern option on Query 2015-12-10 Jeremy Mikola * PHPC-448: Implement ReadConcern class 2015-12-10 Jeremy Mikola * Fix include for mongoc-write-concern-private.h 2015-12-11 Jeremy Mikola * Merge pull request #161 2015-12-11 Hannes Magnusson * Fix package license to be consistent with the source files 2015-12-11 Jeremy Mikola * Merge pull request #160 2015-12-11 Hannes Magnusson * Accept MongoDB 3.2 package repo public keys on test VM 2015-12-11 Jeremy Mikola * Merge pull request #157 2015-12-05 Jeremy Mikola * PHPC-443: Support "bypassDocumentValidation" option in BulkWrite 2015-12-10 Jeremy Mikola * Merge pull request #156 2015-12-10 Jeremy Mikola * Update package repo public key for Travis CI builds 2015-12-10 Jeremy Mikola * Define STANDALONE as MongoDB 3.2 on Travis CI 2015-12-09 Jeremy Mikola * Bump libmongoc for CDRIVER-1046 memory leak fix 2015-12-09 Jeremy Mikola * PHPC-450: failReceivedGetmore does not support getMore commands 2015-12-09 Jeremy Mikola * PHPC-450: Don't assert exact isMaster response when dumping Servers 2015-12-09 Jeremy Mikola * PHPC-450: Split query tests for OP_QUERY and find command 2015-12-09 Jeremy Mikola * Add MongoDB 3.0 replica set test environment 2015-12-09 Jeremy Mikola * PHPC-450: Profiled aggregate commands log the collection NS in 3.2 2015-12-08 Jeremy Mikola * PHPC-450: Update open cursor check for MongoDB 3.2 2015-12-10 Derick Rethans * Merge branch 'pr/152' — fixes PHPC-502 and issue #149 2015-12-10 Derick Rethans * Use more descriptive unused value 2015-12-07 Hannes Magnusson * Fixed PHPC-502: bson_init_static(): precondition failed: data 2015-12-09 Jeremy Mikola * Use consistent name for MongoDB 3.0 test server 2015-12-08 Jeremy Mikola * Merge pull request #155 2015-12-08 Jeremy Mikola * PHPC-450: Enable majority read concern by default in MO 2015-12-08 Jeremy Mikola * PHPC-450: Use MongoDB 3.2 final for testing 2015-12-08 Jeremy Mikola * Make server startup via MO more robust 2015-12-08 Jeremy Mikola * Register STANDALONE-3.0 with the test suite 2015-12-08 Jeremy Mikola * STANDALONE-3.0 port conflicted with STANDALONE-2.4 2015-12-08 Derick Rethans * Merged pull request #151 2015-12-08 Derick Rethans * Bump libmongoc and libbson to 1.3.0 releases 2015-12-02 Derick Rethans * This code has changed in 3.2, and make the error message clear 2015-12-02 Derick Rethans * Added 3.2.0rc5 to our Mongo Orchestration suite 2015-12-02 Derick Rethans * Added some more phpt test leftovers to .gitignore 2015-12-08 Derick Rethans * Merge branch 'v1.0' 2015-12-08 Remi Collet * libmongoc 1.3 is not compatible 2015-12-07 Jeremy Mikola * Revise prep-release.php handling 2015-12-07 Jeremy Mikola * Merge branch 'v1.0' 2015-12-07 Jeremy Mikola * Back to -dev 2015-12-07 Jeremy Mikola * Add 1.0.1 release notes 2015-12-07 Jeremy Mikola * Bump extension version to 1.0.1 2015-12-07 Jeremy Mikola * Revise prep-release.php handling 2015-12-07 Derick Rethans * Merged pull request #150 2015-12-04 Hannes Magnusson * bump mongoc & libbson 2015-12-04 Hannes Magnusson * Generate the mongoc and libbson version files correctly 2015-12-04 Hannes Magnusson * Revert "Unblock compile by copying VERSION_CURRENT and VERSION_RELEASED until CDRIVER-1027 is fixed." 2015-12-03 Jeremy Mikola * Merge pull request #148 2015-12-03 Jeremy Mikola * Master branch is now 1.1.0-dev 2015-12-03 Jeremy Mikola * Add "-dev" to extension version constant 2015-12-02 Derick Rethans * Merged pull request #141 2015-12-02 Derick Rethans * Made error message more consistent as per Jeremy's comment 2015-12-02 Derick Rethans * Move flag exceptions back into config.m4 2015-12-02 Hannes Magnusson * Edgecase compiler warnings in mongoc are mongoc problem, not phongo 2015-12-02 Derick Rethans * Turn off missing braces to make Travis happy 2015-12-02 Derick Rethans * Unblock compile by copying VERSION_CURRENT and VERSION_RELEASED until CDRIVER-1027 is fixed. 2015-12-02 Derick Rethans * Added weak symbols for Windows too 2015-12-02 Derick Rethans * Changed error message to make more sense. 2015-12-02 Derick Rethans * Upgrade libbson and libmongoc to latest master release 2015-12-02 Derick Rethans * Fixed memory leak as per Hannes' comment. 2015-11-20 Derick Rethans * Only list a file once (crept in due to merge conflicts it seems) 2015-11-19 Hannes Magnusson * Temporary workaround for warning in mongoc 2015-11-19 Hannes Magnusson * PHPC-495: Upgrade bundled libbson and libmongoc to 1.3.0 2015-11-19 Hannes Magnusson * PHPC-488: Manager::selectServer() should throw when failing to select a server 2015-11-19 Hannes Magnusson * No need to double-initialize boptions 2015-11-19 Derick Rethans * Renamed struct members due to changes in libmongoc 2015-11-19 Derick Rethans * mongoc_cursor_cursorid_init takes an extra bson_error 2015-11-19 Derick Rethans * Define weak symbols as per a comment in PHPC-406 2015-11-19 Derick Rethans * Add compilation of mongoc_read_concern.c 2015-11-19 Derick Rethans * Bump libbson and libmongoc to 1.3.0beta0 2015-11-17 Derick Rethans * mongoc_topology_description_server_by_id now takes an additional bson_error_t (CDRIVER-906) 2015-11-17 Derick Rethans * Ordered flag has moved into 'flags' struct (CDRIVER-893) 2015-11-17 Derick Rethans * Initial upgrade to pre-1.3.0rc0 version. 2015-12-02 Jeremy Mikola * Merge pull request #135 2015-11-06 Jeremy Mikola * PHPC-487: Regression tests for check_closed stream handler 2015-11-06 Hannes Magnusson * PHPC-487: Reverse logic in check_closed stream handler 2015-11-25 Hannes Magnusson * Its a bit creepy seeing my family in bug reports 2015-11-25 Derick Rethans * Merged pull request #143 2015-11-25 Derick Rethans * PHPC-499: Only add the dependency when we're actually enabling the extension 2015-11-12 Derick Rethans * Merged pull request #137 2015-11-12 Derick Rethans * Wording tweaks after review 2015-11-12 Derick Rethans * HHVM-136: Make hippo and phongo README/CONTRIBUTING files consistent 2015-11-02 Jeremy Mikola * Update documentation for 1.0.0 2015-10-30 Jeremy Mikola * Back to -dev 2015-10-30 Jeremy Mikola * Add 1.0.0 release notes 2015-10-30 Jeremy Mikola * Bump extension version to 1.0.0 2015-10-30 Jeremy Mikola * Merge pull request #130 2015-10-30 Jeremy Mikola * PHPC-475: toJSON and fromJSON should thrown on error 2015-10-28 Jeremy Mikola * Tests for fromJSON() and toJSON() 2015-10-26 Jeremy Mikola * Back to -dev 2015-10-26 Jeremy Mikola * Add 1.0.0RC0 release notes 2015-10-26 Jeremy Mikola * Bump extension version to 1.0.0RC0 2015-10-26 Jeremy Mikola * Revise system libbson version check error message 2015-10-23 Jeremy Mikola * Update GitHub URLs for org change and repo rename 2015-10-22 Jeremy Mikola * Merge pull request #128 2015-10-21 Jeremy Mikola * PHPC-465: Remove WriteConcernException and WriteErrorException 2015-10-21 Jeremy Mikola * Rename WriteConcernError tests 2015-10-21 Jeremy Mikola * PHPC-465: Remove Manager's single write methods 2015-10-20 Jeremy Mikola * PHPC-440: WriteErrorException extends abstract WriteException 2015-10-20 Jeremy Mikola * Merge pull request #127 2015-10-20 Jeremy Mikola * PHPC-462: Remove unused DuplicateKeyException 2015-10-20 Jeremy Mikola * Merge pull request #126 2015-10-19 Jeremy Mikola * PHPC-310: Make BSON types final and disable serialization for now 2015-10-19 Jeremy Mikola * Make BSON create_object assignments consistent 2015-10-16 Jeremy Mikola * PHPC-310: Exception classes need not be final 2015-10-16 Jeremy Mikola * Merge pull request #125 2015-10-15 Jeremy Mikola * PHPC-444: Support options array in BulkWrite and executeInsert() 2015-10-15 Jeremy Mikola * Fix indentation 2015-10-15 Jeremy Mikola * Merge pull request #124 2015-10-14 Jeremy Mikola * PHPC-407: Rename X509 error test and fix cert path 2015-10-14 Jeremy Mikola * Rename X509 connection tests 2015-10-14 Jeremy Mikola * Merge pull request #123 2015-10-14 Jeremy Mikola * PHPC-454: Remove WriteResult::getInfo() method 2015-10-14 Jeremy Mikola * Merge pull request #122 2015-10-14 Jeremy Mikola * PHPC-441: slaveOk bit is now set on hinted secondary query 2015-10-14 Jeremy Mikola * Bump libbson and libmongoc submodules to 1.2.0 2015-10-12 Hannes Magnusson * Merge pull request #121 from bjori/PHPC-256-prod-debug-logs 2015-10-07 Hannes Magnusson * PHPC-256: Productions debug logs 2015-10-07 Hannes Magnusson * PHPC-441: Skip (xfail) these tests while the ticket is being worked on 2015-10-07 Hannes Magnusson * Make sure we have the X509 declaration we need 2015-10-07 Hannes Magnusson * No need for TSRMLS here -- no calls to PHP at all 2015-10-06 Jeremy Mikola * Back to -dev 2015-10-06 Jeremy Mikola * Update install examples to mongodb-beta 2015-10-06 Jeremy Mikola * Add 1.0.0beta2 release notes 2015-10-06 Jeremy Mikola * Avoid nested macros when reporting runtime version in debug mode 2015-10-05 Jeremy Mikola * Omit merge commits from release changelog 2015-10-05 Jeremy Mikola * Use UTC time when creating package.xml 2015-10-05 Jeremy Mikola * Bump extension version to 1.0.0beta2 2015-10-05 Jeremy Mikola * Merge pull request #120 2015-10-05 Remi Collet * PHPC-442: report PHP version in debug info 2015-10-05 Remi Collet * report runtime version in debug mode 2015-10-05 Remi Collet * rename macros 2015-10-04 Remi Collet * report libraries runtime versions 2015-10-05 Jeremy Mikola * Merge pull request #119 2015-10-05 Jeremy Mikola * Test write and WC error extraction for single write methods 2015-10-02 Jeremy Mikola * PHPC-409: $readPreference is no longer sent to non-mongos nodes 2015-10-02 Jeremy Mikola * Update filenames for libmongoc and libbson version functions 2015-10-02 Jeremy Mikola * PHPC-438: Debug handler should display null for no WC error 2015-10-02 Jeremy Mikola * PHPC-436: Handle new writeConcernErrors array in mongoc_write_result_t 2015-10-02 Jeremy Mikola * Bump libbson and libmongoc submodules to 1.2.0-rc0 2015-09-11 Hannes Magnusson * PHPC-415: Add testcase 2015-09-11 Hannes Magnusson * PHPC-415: SSL/TLS already set-up for this stream 2015-09-09 Hannes Magnusson * $readPreferences should not be sent to standalone server 2015-09-09 Hannes Magnusson * Don't provide server_id when we have none 2015-10-01 Jeremy Mikola * Merge pull request #83 2015-10-01 Jeremy Mikola * Use versioned URI for mongo-orchestration 2015-10-01 Jeremy Mikola * Increase mongo-orchestration HTTP timeout 2015-08-20 Jeremy Mikola * Empty query results should still pass "find" phase in mo-tests 2015-08-20 Jeremy Mikola * Implement "clientHosts" phase for mo-tests 2015-08-19 Jeremy Mikola * Support "delete" operation in mo-tests 2015-08-19 Jeremy Mikola * Rename "findOne" to "find" in mo-tests 2015-08-19 Jeremy Mikola * Fix exception throwing in mo-tests conversion script 2015-09-28 Jeremy Mikola * Merge pull request #118 2015-09-24 Jeremy Mikola * PHPC-393: Ignore non-public properties when encoding BSON 2015-09-24 Jeremy Mikola * Previous break statement makes the else condition redundant 2015-09-24 Jeremy Mikola * Merge pull request #117 2015-09-23 Jeremy Mikola * PHPC-430, PHPC-377: Do not convert Query filter arg to an object 2015-08-27 Hannes Magnusson * PHPC-377: Eliminate object casting and whole lot of zend hash helpers 2015-08-25 Hannes Magnusson * PHPC-373: Get rid of MAKE_STD_ZVAL() and use bson_t instead 2015-09-23 Jeremy Mikola * PHPC-430: Regression tests for Query arg corruption 2015-09-23 Jeremy Mikola * Merge pull request #116 2015-09-23 Jeremy Mikola * PHP versions in .travis.yml don't need to be strings 2015-08-27 Hannes Magnusson * PHPC-379: I broke PHP5.3 build. Thats OK, since we don't support it. 2015-09-23 Jeremy Mikola * Merge pull request #115 2015-09-23 Jeremy Mikola * PHPC-427: Fix parsing of null WC journal param for PHP 5.4 2015-09-22 Jeremy Mikola * PHPC-428: Remove support for WriteConcern fsync option 2015-09-22 Jeremy Mikola * Update arg info for WriteConcern $w ctor parameter 2015-09-22 Jeremy Mikola * Merge pull request #113 2015-09-21 Jeremy Mikola * PHPC-427: Do not set WC journal/fsync to false for NULL args 2015-09-22 Jeremy Mikola * Merge pull request #110 2015-09-18 Jeremy Mikola * Additional tests for WriteConcern debug handler 2015-09-18 Jeremy Mikola * PHPC-423: WriteConcern should report default "w" option as null 2015-09-22 Jeremy Mikola * Merge pull request #109 2015-09-17 Jeremy Mikola * PHPC-426: WC ctor should throw for invalid $w and $wtimeout args 2015-09-17 Jeremy Mikola * PHPC-425: WC ctor should accept int/string $w args w/o casting 2015-09-17 Jeremy Mikola * WriteConcern ctor error test doesn't need EXPECTF 2015-09-17 Jeremy Mikola * Use throws() helper function in WriteConcern ctor error test 2015-09-22 Jeremy Mikola * Merge pull request #106 2015-09-18 Derick Rethans * Skip logging tests for HHVM, which will use its own method 2015-09-10 Derick Rethans * Better messages for when things go wrong with exceptions 2015-09-10 Derick Rethans * PHPC-412: HHVM does not do SSL peer verification like PHP 2015-09-18 Jeremy Mikola * Merge pull request #111 2015-09-18 Jeremy Mikola * PHPC-410: Make BSON exception message consistent with HHVM 2015-09-17 Jeremy Mikola * Merge pull request #103 2015-09-17 Jeremy Mikola * Split out UTCDateTime toDateTime and toString tests 2015-09-15 Jeremy Mikola * PHPC-410: zval_to_bson() should throw on non-Serializable Type objects 2015-09-15 Jeremy Mikola * PHPC-410: object_to_bson() should throw on unsupported BSON\Type objects 2015-09-09 Jeremy Mikola * PHPC-410: object_to_bson() should encode non-stdClass objects 2015-09-09 Jeremy Mikola * Revise debug messages in object_to_bson() 2015-09-17 Jeremy Mikola * Merge pull request #108 2015-09-16 Jeremy Mikola * PHPC-418: Getters for WriteConcern properties 2015-09-16 Jeremy Mikola * Rename WriteConcern tests 2015-09-16 Jeremy Mikola * Move PHONGO_WRITE_CONCERN_W_MAJORITY definition to php_phongo.h 2015-09-15 Jeremy Mikola * Revise ReadPreference constructor error messages 2015-09-15 Jeremy Mikola * Rename first ReadPreference constructor arg to "mode" 2015-09-15 Jeremy Mikola * PHPC-418: Getters for ReadPreference properties 2015-09-15 Jeremy Mikola * Use valid tag sets in ReadPreference tests 2015-09-15 Jeremy Mikola * Rename ReadPreference tests and split constructor error test 2015-09-16 Jeremy Mikola * Merge pull request #107 2015-09-15 Jeremy Mikola * PHPC-417: Return value objects from Manager RP/WC getters 2015-09-15 Jeremy Mikola * Declare phongo_cursor_init() statically 2015-09-14 Jeremy Mikola * Merge pull request #102 2015-09-09 Jeremy Mikola * PHPC-408: Ensure object_to_bson() always creates a BSON document 2015-09-09 Jeremy Mikola * Refactor bson-utcdatetime-001.phpt 2015-09-10 Jeremy Mikola * Back to -dev 2015-09-10 Jeremy Mikola * Add 1.0.0beta1 release notes 2015-09-10 Jeremy Mikola * Add line break between versions in release notes 2015-09-10 Jeremy Mikola * Bump extension version to 1.0.0beta1 2015-09-09 Jeremy Mikola * Merge pull request #98 2015-09-09 Jeremy Mikola * PHPC-381: Print whether profile commands were successful 2015-09-02 Jeremy Mikola * PHPC-381: Server::executeQuery/Command() should take a read preference 2015-09-04 Jeremy Mikola * Include unknown error domain in log messages 2015-09-02 Jeremy Mikola * Fall back to driver's RuntimeException instead of SPL 2015-09-04 Hannes Magnusson * Merge pull request #100 from bjori/master 2015-09-04 Hannes Magnusson * s/10gen-labs/mongodb-labs/g after org changes 2015-09-03 Hannes Magnusson * Merge pull request #99 from bjori/master 2015-08-20 Hannes Magnusson * Bump libmongoc to 1.2-beta1 2015-09-02 Derick Rethans * Merged pull request #95 2015-09-02 Derick Rethans * Disable the test for a double wrap with IteratorIterator() 2015-09-02 Derick Rethans * Disable test that dumps hex codes for generated BSON 2015-09-02 Derick Rethans * Merged pull request #96 2015-09-02 Derick Rethans * Fixed getServers test to include milliseconds in UTCDate dumps 2015-09-02 Jeremy Mikola * Merge pull request #92 2015-08-30 Jeremy Mikola * Clean up BSON error tests 2015-09-01 Jeremy Mikola * Merge pull request #80 2015-08-14 Jeremy Mikola * PHPC-361: Manager::getServers() should omit unknown servers 2015-09-01 Derick Rethans * Merged pull request #91 2015-08-28 Derick Rethans * HHVM encodes __pclass last, so disable these tests here. 2015-08-26 Derick Rethans * phpinfo() behaves totally different in HHVM 2015-08-28 Derick Rethans * Merged pull request #89 2015-08-27 Derick Rethans * HHVM does not allow for current() on an object 2015-08-27 Derick Rethans * Split tests for invalid arguments out into their own files, and ignore them for HHVM 2015-08-28 Jeremy Mikola * Merge pull request #88 2015-08-26 Jeremy Mikola * PHPC-337: BSON\Javascript debug handler 2015-08-26 Jeremy Mikola * PHPC-339: BSON\Timestamp debug handler 2015-08-26 Jeremy Mikola * PHPC-340: BSON\UTCDateTime debug handler 2015-08-26 Jeremy Mikola * PHPC-338: BSON\Regex debug handler 2015-08-26 Jeremy Mikola * Fix test expectation for builds with top-level BSON namespace 2015-08-21 Jeremy Mikola * Merge pull request #85 2015-08-21 Hannes Magnusson * Don't be printing out these commands during execution 2015-08-21 Hannes Magnusson * Back to -dev 2015-08-21 Hannes Magnusson * PHPC-366: Update release script to use RELEASE-x.y file 2015-08-21 Hannes Magnusson * PHPC-366: Merge 1.0.x release notes into RELEASE-1.0 2015-08-21 Hannes Magnusson * PHPC-366: Merge RELEASE-0.* release notes into RELEASE-0 2015-08-20 Jeremy Mikola * Add 1.0.0alpha2 release notes 2015-08-20 Jeremy Mikola * Bump extension version to 1.0.0alpha2 2015-08-20 Jeremy Mikola * Merge pull request #84 2015-08-20 Jeremy Mikola * PHPC-365: Add src/contrib to Windows build includes 2015-08-20 Jeremy Mikola * Merge pull request #81 2015-08-20 Jeremy Mikola * Add 1.0.0alpha1 release notes 2015-08-18 Jeremy Mikola * Bump extension version to 1.0.0alpha1 2015-08-18 Jeremy Mikola * Bump minimum PHP version requirement to 5.4 2015-08-18 Jeremy Mikola * Use php.net email addresses for authors 2015-08-20 Hannes Magnusson * Link to the HHVM project 2015-08-20 Hannes Magnusson * Test running belongs to CONTRIBUTING.md 2015-08-20 Hannes Magnusson * Add docs for the new PHONGO_SERVERS environment variable 2015-08-20 Hannes Magnusson * We don't tail master 2015-08-20 Hannes Magnusson * Merge pull request #82 from derickr/test-name-and-servers 2015-08-20 Derick Rethans * Do this with an env var instead 2015-08-19 Jeremy Mikola * Fix str_replace() newline replacement 2015-08-19 Derick Rethans * Allow for PHONGO-SERVERS.json in ~ (and fix a test case name) 2015-08-14 Jeremy Mikola * Merge pull request #76 2015-08-14 Jeremy Mikola * Strip newlines from exception messages for more concise failures 2015-08-05 Derick Rethans * Added the error message to the failure cases. 2015-08-14 Jeremy Mikola * Merge pull request #70 2015-08-14 Jeremy Mikola * Add mongoc-host-list.c to config sources 2015-08-14 Jeremy Mikola * Fix indentation in config.m4 sources 2015-08-14 Jeremy Mikola * Bump libmongoc submodule to 1.2.0-beta 2015-07-30 Jeremy Mikola * Restore -Werror compile flag for 5.4+ developer builds 2015-08-14 Jeremy Mikola * Merge pull request #78 2015-08-07 Jeremy Mikola * PHPC-271: Server::executeBulkWrite() should take a write concern 2015-08-13 Jeremy Mikola * Merge pull request #77 2015-08-05 Jeremy Mikola * Split out Manager constructor error tests 2015-08-05 Jeremy Mikola * Manager should check client pointer before destroying it 2015-08-03 Jeremy Mikola * PHPC-196: Implement Manager getters for WC and RP 2015-08-05 Jeremy Mikola * PHPC-353: Return early when there are no options to apply 2015-08-05 Jeremy Mikola * PHPC-353: Support RP and WC in Manager options array 2015-08-05 Jeremy Mikola * Manager constructor should check if URI or client creation fails 2015-07-31 Jeremy Mikola * Fix memory leak in _phongo_debug_bson() 2015-08-13 Jeremy Mikola * Merge pull request #79 2015-08-13 Jeremy Mikola * Trim #includes, since src/contrib is already an include path 2015-08-05 Jeremy Mikola * Merge pull request #75 2015-08-05 Jeremy Mikola * PHPC-357: Revise test and relocate to standalone group 2015-08-04 Derick Rethans * PHPC-357: "invalid namespace" exception should report the namespace 2015-08-05 Jeremy Mikola * Merge pull request #74 2015-08-04 Derick Rethans * PHPC-129: Split out WriteConcern constructor error test 2015-08-04 Derick Rethans * Merged pull request #73 2015-08-03 Derick Rethans * Rename BSON\Binary's subType field and getSubType() method to type and getType() 2015-08-04 Derick Rethans * Merged pull request #72 2015-07-31 Derick Rethans * Temporary fix for the NULL vs null issue 2015-08-03 Hannes Magnusson * Make the relative path work 2015-08-03 Hannes Magnusson * Skip test when not using the test vms 2015-07-30 Jeremy Mikola * Merge pull request #69 2015-07-30 Jeremy Mikola * PHPC-350: Bump libmongoc submodule for updated headers 2015-07-30 Jeremy Mikola * Merge pull request #68 2015-07-30 Jeremy Mikola * bson_to_zval() should always initialize state->zchild 2015-07-29 Jeremy Mikola * Update extension filename in Travis scripts 2015-07-29 Jeremy Mikola * PHPC-347: bson_to_zval() leaks when buffer contains no documents 2015-07-29 Jeremy Mikola * PHPC-345: bson_to_zval() should throw exceptions instead of warnings 2015-07-29 Jeremy Mikola * Merge pull request #67 2015-07-28 Jeremy Mikola * PHPC-334: Split hex_dump() test case 2015-07-29 Jeremy Mikola * Merge pull request #64 2015-07-27 Jeremy Mikola * PHP 5.3 compatibility for tools.php 2015-07-27 Jeremy Mikola * Define str_efree() macro for PHP 5.3 compatibility 2015-07-27 Jeremy Mikola * Compile with no-cast-qual for PHP 5.3 2015-07-27 Jeremy Mikola * PHPC-344: Allow non-root Serializable to encode as BSON array 2015-07-27 Jeremy Mikola * PHPC-343: Allow bsonSerialize() to return a stdClass 2015-07-27 Jeremy Mikola * PHPC-331: Tests for BSON deserialization errors 2015-07-27 Jeremy Mikola * PHPC-329: bson_to_zval() serialization spec compatibility 2015-07-27 Jeremy Mikola * PHPC-329: __pclass must be both instantiatable and Persistable 2015-07-27 Jeremy Mikola * PHPC-329: Apply more validation to type map class 2015-07-24 Jeremy Mikola * PHPC-336: BSON\Binary debug handler 2015-07-28 Jeremy Mikola * Merge pull request #66 2015-07-28 Derick Rethans * Assert what the tests want, and not more 2015-07-28 Derick Rethans * HHVM does not include the function name, and has two lines of extra stack trace 2015-07-24 Jeremy Mikola * Merge pull request #63 2015-07-24 Jeremy Mikola * PHPC-341: Ensure bson_t is freed after decoding JSON 2015-07-22 Jeremy Mikola * Merge pull request #62 2015-07-22 Jeremy Mikola * PHPC-333: Implement MongoDB\BSON\Binary::getData() 2015-07-22 Jeremy Mikola * Fix proto for Binary::getSubType() 2015-07-22 Jeremy Mikola * Merge pull request #59 2015-07-15 Hannes Magnusson * bump debug tests after slight tracing changes 2015-07-15 Hannes Magnusson * PHPC-229: Support options array in second parameter of Manager ctor 2015-07-22 Jeremy Mikola * Merge pull request #61 2015-07-21 Jeremy Mikola * PHPC-334: Don't produce BSON with multiple __pclass fields 2015-07-21 Jeremy Mikola * Merge pull request #60 2015-07-21 Jeremy Mikola * Don't build with -Werror until CDRIVER-757 is resolved 2015-07-20 Jeremy Mikola * PHPC-330: Always include __pclass property when unserializing BSON 2015-07-15 Hannes Magnusson * Add -Werror into --enable-developer-flags 2015-07-15 Hannes Magnusson * Move the php_array to contrib/ and rename to _api 2015-07-14 Hannes Magnusson * We are tracking 1.2.0-dev, not master! 2015-07-15 Jeremy Mikola * Merge pull request #56 2015-07-11 Jeremy Mikola * Use namespace-agnostic BSON (de)serialization functions 2015-07-11 Jeremy Mikola * Fix from/toJSON() protos 2015-07-11 Jeremy Mikola * PHPC-311: Rename from/toArray() functions to from/toPHP() 2015-07-10 Jeremy Mikola * PHPC-315: Support "root" type mapping for top-level documents 2015-07-06 Jeremy Mikola * PHPC-319: Convert top-level documents to stdClass by default 2015-07-07 Jeremy Mikola * Relax expected class instance in Manager: getServers() test 2015-07-07 Jeremy Mikola * Use plural property name to store list of Address objects 2015-07-07 Jeremy Mikola * Fix WriteResult::getWriteConcernError() proto 2015-07-08 Hannes Magnusson * Force 'E' to be present in php.ini so environment variables are picked up 2015-07-07 Hannes Magnusson * The MongoDB 3.0 repo was moved. 2015-07-07 Hannes Magnusson * Don't start/stop servers on travis. We don't use MO here yet 2015-07-07 Hannes Magnusson * PHPC-304: Enable the test again -- and fix typo in the clean section! 2015-07-07 Hannes Magnusson * Add the START() servers to PHONGO-SERVERS, and remove it with DELETE() 2015-07-07 Hannes Magnusson * PHPC-303: Cannot connect to healthy Replica Set if seedlist only contains a secondary 2015-07-07 Jeremy Mikola * Merge pull request #57 2015-07-06 Jeremy Mikola * PHPC-325: bson_to_zval() leaks when buffer contains multiple documents 2015-07-06 Jeremy Mikola * Merge pull request #55 2015-06-17 Jeremy Mikola * PHPC-306: Check for sasl_client_done in config.m4 2015-07-01 Jeremy Mikola * Update expected float output after libbson bump 2015-07-01 Jeremy Mikola * Bump libbson and libmongoc submodules 2015-07-06 Jeremy Mikola * Merge pull request #51 2015-07-06 Jeremy Mikola * Remove redundant array conversions in phongo_query_init() 2015-07-06 Jeremy Mikola * PHPC-317: Ensure "sort" query option serializes as BSON object 2015-06-30 Hannes Magnusson * PHPC-323: The check for system mongoc checks system bson, not mongoc 2015-06-30 Hannes Magnusson * PHPC-322: Wrong bugtracker URL in configure output 2015-06-30 Hannes Magnusson * PHPC-321: UTCDatetime -> UTCDateTime 2015-06-30 Hannes Magnusson * PHPC-321: UTCDatetime -> UTCDateTime 2015-06-30 Hannes Magnusson * PHPC-309: Bump tests 2015-06-30 Hannes Magnusson * PHPC-309: Move the BSON namespace under MongoDB\ namespace 2015-06-30 Jeremy Mikola * Merge pull request #50 from 10gen-labs/jmikola-patch-1 2015-06-29 Jeremy Mikola * Merge pull request #49 2015-06-21 Jeremy Mikola * LDAP VM does not require python-pip (or epel) 2015-06-29 Jeremy Mikola * Merge pull request #53 2015-06-29 Jeremy Mikola * PHPC-308: Skip getmore test until libmongoc issues are resolved 2015-06-21 Jeremy Mikola * Update install docs, since we now have a PECL package 2015-06-09 Hannes Magnusson * bump submodule, hopfully fixing build 2015-06-09 Hannes Magnusson * Fix build after some SDAM changes 2015-06-09 Hannes Magnusson * install mongo-c-driver required building blocks 2015-06-09 Hannes Magnusson * PHPC-308: Failed getmore should throw exception 2015-05-22 Hannes Magnusson * There is no need for these tests to be this slow -- safes 2seconds now 2015-05-22 Hannes Magnusson * Cluster tests are slow 2015-05-20 Hannes Magnusson * Fix test -- this isn't a hardcoded ID 2015-05-20 Hannes Magnusson * Move MO host resolving to tools 2015-05-20 Hannes Magnusson * PHPC-304: Add a failGetMore trigger 2015-05-20 Hannes Magnusson * PHPC-291: New cluster/socket/connection tests 2015-05-20 Hannes Magnusson * PHPC-291: Add a script to convert mo-tests (JSON) to PHPT 2015-05-20 Hannes Magnusson * These are no longer used 2015-05-18 Hannes Magnusson * Organize cursor tests 2015-05-20 Hannes Magnusson * Merge pull request #46 from remicollet/issue-driver 2015-05-20 Remi Collet * PHPC-305: add --with-libmongo option 2015-05-18 Hannes Magnusson * Add a helper to know if we are in predictable (vagrant) env or not 2015-05-18 Hannes Magnusson * Fix server IDs 2015-05-13 Hannes Magnusson * Improve code coverage for the WriteException 2015-05-13 Hannes Magnusson * Add test for the info/ini section 2015-05-13 Hannes Magnusson * Improve code covergae 2015-05-13 Hannes Magnusson * PHPC-75: Improve debug output coverage 2015-05-13 Hannes Magnusson * Use the defines 2015-05-13 Hannes Magnusson * fix test after moving it around 2015-05-13 Hannes Magnusson * PHPC-75: Improve coverage 2015-05-13 Hannes Magnusson * improve code coverage 2015-05-13 Hannes Magnusson * Improve test organization 2015-05-13 Hannes Magnusson * PHPC-75: Server error code coverage 2015-05-13 Hannes Magnusson * Fix test on travis 2015-05-13 Hannes Magnusson * PHPC-301: var_dump()ing Manager should show debug info 2015-05-13 Hannes Magnusson * PHPC-300: Add var_dump() debug info for Server 2015-05-13 Hannes Magnusson * PHPC-75: Improve coverage for the Manager 2015-05-13 Hannes Magnusson * PHPC-277: Ensure Query always serializes $query as a BSON object 2015-05-13 Hannes Magnusson * Split the test into success/failure 2015-05-13 Hannes Magnusson * PHPC-299: Annoying compiler warning 2015-05-13 Hannes Magnusson * PHPC-298: Coalesce small writes 2015-05-13 Hannes Magnusson * PHPC-284: Fix LogicException declaration 2015-05-12 Hannes Magnusson * bump submodules 2015-05-12 Hannes Magnusson * PHPC-279: Add 2.4 (and 2.6) to build matrix and ensure test suite compatibility 2015-05-06 Hannes Magnusson * PHPC-296: phongo.debug created for empty values 2015-05-06 Hannes Magnusson * Bump version 2015-05-06 Hannes Magnusson * Add 0.6.3 release notes 2015-05-06 Hannes Magnusson * prep for 0.6.3 2015-05-06 Hannes Magnusson * PHPC-294: Fix path to build directory 2015-05-06 Jeremy Mikola * back to -dev 2015-05-06 Jeremy Mikola * Add 0.6.2 release notes 2015-05-06 Jeremy Mikola * Bump stability 2015-05-06 Jeremy Mikola * back to -dev 2015-05-06 Jeremy Mikola * Add 0.6.1 release notes 2015-05-06 Jeremy Mikola * Bump stability 2015-05-05 Hannes Magnusson * Fix build outside of srcdir 2015-05-04 Hannes Magnusson * back to -dev 2015-05-04 Hannes Magnusson * Add 0.6.0 release notes 2015-05-04 Hannes Magnusson * Bump stability 2015-05-04 Hannes Magnusson * Exceptions live in their own folder now 2015-05-04 Hannes Magnusson * Add coveralls badger 2015-05-04 Hannes Magnusson * Use the coveralls token for 10gen-labs/mongo-php-driver-prototype not my personal one 2015-05-04 Jeremy Mikola * Merge pull request #45 from jmikola/multiple-toArray 2015-05-04 Jeremy Mikola * PHPC-282: Test for multiple Cursor::toArray() calls 2015-05-04 Jeremy Mikola * Merge pull request #44 from jmikola/phpc-255 2015-05-04 Jeremy Mikola * PHPC-255: Cursors cannot rewind after starting iteration 2015-05-04 Jeremy Mikola * PHPC-282: Remove tests for multiple iterators on the same Cursor 2015-05-04 Jeremy Mikola * PHPC-282: Cursor should not yield multiple iterators 2015-05-04 Jeremy Mikola * PHPC-284: Create MongoDB\Driver\Exception\LogicException class 2015-05-04 Jeremy Mikola * Merge pull request #43 from jmikola/phpc-283 2015-05-04 Jeremy Mikola * Use common return for zval_to_bson() bsonSerialize() error path 2015-05-04 Jeremy Mikola * PHPC-283: UnexpectedValueException for invalid bsonSerialize() return value 2015-05-04 Jeremy Mikola * Merge pull request #42 from jmikola/phpc-179 2015-05-01 Jeremy Mikola * PHPC-280: WriteConcern should always set journal/fsync boolean args 2015-05-01 Jeremy Mikola * Document WriteConcern $w param as integer|string 2015-05-01 Jeremy Mikola * PHPC-179: Show unset journal/fsync as null in WriteConcern debug handler 2015-05-04 Jeremy Mikola * Merge pull request #40 from jmikola/phpc-274 2015-04-26 Jeremy Mikola * PHPC-274: Regression test for root BSON\Serializable encoding 2015-04-26 Jeremy Mikola * PHPC-275: object_to_bson() handling for invalid bsonSerialize() retval 2015-04-24 Jeremy Mikola * PHPC-274: Fix zval_to_bson() encoding of BSON\Serializable objects 2015-05-04 Jeremy Mikola * Merge pull request #41 from jmikola/phpc-278 2015-04-30 Jeremy Mikola * PHPC-278: nModified may be null for legacy writes 2015-04-27 Hannes Magnusson * PHPC-269: Travis mojo again 2015-04-24 Hannes Magnusson * PHPC-272: Move exceptions into MongoDB\Driver\Exception namespace 2015-04-24 Hannes Magnusson * Post-release-bump-version 2015-04-24 Hannes Magnusson * Add 0.5.1 release notes 2015-04-24 Hannes Magnusson * Bump version to 0.5.1-alpha 2015-04-24 Hannes Magnusson * Include the pre-generated fixtures in the package 2015-04-24 Hannes Magnusson * PHPC-241: Don't try to use local timezone 2015-04-24 Hannes Magnusson * Fix extension name -- and recommend the developers flags 2015-04-24 Hannes Magnusson * PHPC-241: mongodb.debug improvements 2015-04-24 Hannes Magnusson * Fix unused result warning - and use the localtime in logs 2015-04-23 Hannes Magnusson * Update testing section and add related section 2015-04-23 Hannes Magnusson * Fix coveralls build 2015-04-23 Hannes Magnusson * PHPC-270: Several test fail because of missing enableTestCommands 2015-04-23 Hannes Magnusson * PHPC-270: add TESTCOMMANDS() skipif to confirm mongod is running with required options 2015-04-23 Hannes Magnusson * PHPC-269: Fix travis setup 2015-04-23 Hannes Magnusson * PHPC-268: Update tests to declare which environments they need 2015-04-23 Hannes Magnusson * PHPC-268: Add NEEDS() function to check if that environment is available 2015-04-23 Hannes Magnusson * Object IDs change, fix test 2015-04-23 Hannes Magnusson * PHPC-247: Remove 'faker' as prerequisite from running our full test suite 2015-04-23 Hannes Magnusson * PHPC-247: Remove on-the-fly composer generated fixtures 2015-04-23 Hannes Magnusson * PHPC-247: Use the bundled pregenerated fixtures 2015-04-23 Hannes Magnusson * PHPC-89: Bundle generated fixtures and make them easily loadable 2015-04-23 Hannes Magnusson * PHPC-260: Allow/use "object" in setTypeMap() as alias/preferred for "stdclass" 2015-04-23 Hannes Magnusson * PHPC-267; _id generated on embedded document 2015-04-23 Hannes Magnusson * PHPC-265: BSON encoding unsupoprted types (Resource) should fail 2015-04-23 Hannes Magnusson * PHPC-266: Add MongoDB\Driver\UnexpectedValueException 2015-04-22 Hannes Magnusson * Bump copyright -- happy 2015 2015-04-22 Hannes Magnusson * PHPC-75: Improve code coverage 2015-04-22 Hannes Magnusson * No need for code-coverage for contrib 2015-04-23 Hannes Magnusson * Merge pull request #39 from remicollet/issue-phpc258 2015-04-23 Remi Collet * PHPC-258: make all filed needed for test as role="test" 2015-04-22 Hannes Magnusson * Merge branch 'remicollet-issue-libbson' 2015-04-22 Remi Collet * PHPC-259: add --with-libbson option 2015-04-21 Jeremy Mikola * Mongo Orchestration now works with PyMongo 3.0 2015-04-21 Hannes Magnusson * Back to -dev 2015-04-21 Hannes Magnusson * Add 0.5.0 release notes 2015-04-21 Hannes Magnusson * Bump stability 2015-04-21 Hannes Magnusson * Fix tests on 5.3 -- and use consistent db/collection 2015-04-21 Hannes Magnusson * Fix test - set my favorite ini option: date.timezone 2015-04-21 Hannes Magnusson * Fix tests 2015-04-21 Hannes Magnusson * PHPC-241: Include lib versions and uri in the logs 2015-04-21 Hannes Magnusson * Use the pretty MONGOC macros 2015-04-21 Hannes Magnusson * Remove dead code 2015-04-21 Hannes Magnusson * Move the init function to where all the others are and add folding markers 2015-04-21 Jeremy Mikola * Merge pull request #37 2015-04-17 Jeremy Mikola * Current element is already freed in php_phongo_cursor_free() 2015-04-16 Jeremy Mikola * Test Cursor iteration handlers and ensure rewind doesn't reset position 2015-04-16 Jeremy Mikola * Tests for multiple iterators sharing the same Cursor 2015-04-15 Jeremy Mikola * PHPC-240: Rely on libmongoc for command cursor iteration 2015-04-14 Jeremy Mikola * PHPC-240: Regression tests for command cursor getmore 2015-04-21 Hannes Magnusson * PHPC-254: Remove unused RINIT and RSHUTDOWN handlers 2015-04-21 Hannes Magnusson * PHPC-253: bump mongoc after CDRIVER-611 fix 2015-04-16 Hannes Magnusson * PHPC-249: empty array should be serialized as array 2015-04-16 Hannes Magnusson * PHPC-248: Allow ->setTypeMap() to set 'array' and 'stdclass' 2015-04-15 Hannes Magnusson * PHPC-245: Allow embedding objects in updates 2015-04-15 Hannes Magnusson * PHPC-245: executeUpdate() converts objects to arrays 2015-04-14 Hannes Magnusson * PHPC-244: Cannot use object of type Person as array 2015-04-14 Hannes Magnusson * PHPC-243: Manager->executeUpdate() option is supposed to be 'multi' 2015-04-14 Hannes Magnusson * Merge pull request #35 from bjori/PHPc-239 2015-04-14 Hannes Magnusson * PHPC-239: Cursor refcount issues 2015-04-14 Hannes Magnusson * Merge pull request #36 from derickr/align-and-missing-break-comment 2015-04-14 Derick Rethans * Align code and added the "break intentionally ommitted" comment 2015-04-13 Hannes Magnusson * PHPC-237: Update PHP version requirement in package.xml 2015-04-10 Hannes Magnusson * post-release pump 2015-04-10 Hannes Magnusson * Add 0.4.1 release notes 2015-04-10 Jeremy Mikola * Prep 0.4.1 release 2015-04-10 Hannes Magnusson * PHPC-236: 5.3-zts build broken 2015-04-10 Hannes Magnusson * Back to -dev 2015-04-10 Hannes Magnusson * prep 0.4.0 release 2015-04-10 Hannes Magnusson * Add 0.4.0 release notes 2015-04-10 Hannes Magnusson * Install ext/zlib so we can pecl install .tgz 2015-04-10 Hannes Magnusson * mo will automatically upgrade pymongo -- we need to downgrade 2015-04-10 Hannes Magnusson * mongo-orchestration isn't happy about the recent pymongo3.0 release 2015-04-10 Jeremy Mikola * Update description for Cursor::getServer() 2015-04-09 Hannes Magnusson * PHPC-234: Run test suite automatically on FreeBSD 10.1 2015-04-09 Hannes Magnusson * PHPC-235: Fix out-of-src builds on FreeBSD 2015-04-09 Hannes Magnusson * Initial script to provision on FreeBSD 2015-04-09 Hannes Magnusson * Initial script to provision on Windows 2015-04-09 Hannes Magnusson * Fix windows build 2015-04-09 Hannes Magnusson * Simplify hash and fix windows build 2015-04-09 Hannes Magnusson * Rename the compat header - its much more then PHP5.3 issues now 2015-04-09 Hannes Magnusson * Fix build on windows -- no strtoll() 2015-04-09 Hannes Magnusson * Fix warning, return in noreturn function 2015-04-09 Hannes Magnusson * Fix zts build 2015-04-09 Hannes Magnusson * Fix php_flock() warning on windows 2015-04-09 Hannes Magnusson * PHPC-213: Disable extra bson type alignment 2015-04-09 Hannes Magnusson * Bumpidy bump 2015-04-09 Hannes Magnusson * PHPC-233: Mark the ctor as private for internally created value objects 2015-04-08 Hannes Magnusson * PHPC-80: Create distcheck target 2015-04-08 Hannes Magnusson * Convert int64 that overflow 32bit long to strings 2015-04-08 Hannes Magnusson * Convert overflown int64 to strings and print a warning 2015-04-08 Hannes Magnusson * Fix path to tests when executed through pecl run-tests 2015-04-08 Hannes Magnusson * Ignore untracked files in these repos 2015-04-08 Hannes Magnusson * libbson & mongoc seem to have fixed a lot of warnings -- enable all of ours 2015-04-08 Hannes Magnusson * Workaround CDRIVER-610 2015-04-08 Hannes Magnusson * Apparently there is a function for this! 2015-04-08 Hannes Magnusson * Fix zts build.. TSRMLS_FETCH_FROM_CTX declares variables and therefore must come first 2015-04-07 Hannes Magnusson * Remove noop log handler 2015-04-07 Hannes Magnusson * PHPC-231: Manager instances should not free streams that are still in use 2015-04-07 Hannes Magnusson * bump dependencies for PHPC-231 & PHPC-213 2015-04-07 Jeremy Mikola * PHPC-232: Fix capitalization for WriteResult::getWriteConcern() 2015-04-07 Jeremy Mikola * PHPC-231: Regression test for Manager destruct stream freeing 2015-04-06 Jeremy Mikola * Merge pull request #33 2015-04-06 Jeremy Mikola * Remove unnecessary php_phongo_cursor_free_current() call 2015-04-06 Jeremy Mikola * Re-use cursor_free_current() in cursor_free() 2015-04-06 Jeremy Mikola * PHPC-215: Fix Cursor iteration through IteratorIterator 2015-04-03 Jeremy Mikola * PHPC-225: Test Cursor::isDead() and kill on destruct 2015-04-03 Jeremy Mikola * PHPC-224: Consolidate Result and Cursor classes into one 2015-04-03 Jeremy Mikola * PHPC-224: Remove Cursor class, which implements Iterator 2015-04-03 Hannes Magnusson * PHPC-207: Correct serialized data examples for ODS documentation 2015-04-03 Hannes Magnusson * PHPC-210 & PHPC-209 & PHPC-207 Fix BSON ODM/ODS 2015-04-03 Hannes Magnusson * PHPC-208: Restrict ODS to "__pclass" fieldnames 2015-04-03 Hannes Magnusson * PHPC-194: Implement Manager::selectServer() method to wrap SDAM server selection 2015-04-03 Hannes Magnusson * In PHP5.3 we hit the __wakeUp() which has slightly different exception 2015-04-03 Hannes Magnusson * Merge pull request #34 from serebro/patch-1 2015-04-03 Sergey * Docs small fix 2015-04-03 Hannes Magnusson * PHPC-190: Provide __wakeUp() to disable unserialize() 2015-04-03 Hannes Magnusson * This apt-get update is slow -- no need to execute it all the time 2015-04-03 Hannes Magnusson * PHPC-191 && PHPC-192: Add verify_expiry && verify_peer_name certificate verify options 2015-04-02 Hannes Magnusson * PHPC-223: Use explicit SSL options rather then stream context 2015-04-02 Hannes Magnusson * Fix setting debug logging as part of the driverOptions 2015-04-02 Hannes Magnusson * Private Public doesn't exists... This is supposed to be private :D 2015-04-02 Hannes Magnusson * Cleanup after test 2015-04-02 Hannes Magnusson * Make it possible to cleanup other db and collections used 2015-04-01 Hannes Magnusson * Fix tests when executed outside of srcroot 2015-04-01 Hannes Magnusson * PHPC-222: WriteConcernError can cause segfaults on Ubuntu Precise 32bit 2015-04-01 Hannes Magnusson * PHPC-220: BSON\UTCDatetime broken on 32bit 2015-04-01 Hannes Magnusson * Fix compile warning on 32bit 2015-04-01 Hannes Magnusson * Fix incompatible pointer type in PHP 5.3 2015-04-01 Hannes Magnusson * Include usable gdbinit 2015-04-01 Hannes Magnusson * PHPC-221: Add Ubuntu Precise (12.04.5) 32bit image 2015-04-01 Hannes Magnusson * PHPC-219 - BSON\Javascript segfaults on Ubuntu Precise 32bit 2015-04-01 Hannes Magnusson * PHPC-221: Rename the identifier to precise64 as we'll be adding 32bit soon 2015-03-31 Jeremy Mikola * Merge pull request #32 2015-03-31 Jeremy Mikola * PHPC-204: Result::toArray() should respect type map configuration 2015-03-31 Jeremy Mikola * PHPC-203: Result::toArray() should proxy iterator_to_array($this) 2015-03-31 Hannes Magnusson * Make sure we install the latest package in case of multiple rebuilds of same name 2015-03-31 Jeremy Mikola * Merge pull request #31 2015-03-30 Jeremy Mikola * PHPC-214: Result does not need custom iterator classes 2015-03-30 Hannes Magnusson * Forcefully install the new archive, even though it exists 2015-03-30 Hannes Magnusson * PHPC-216: PHP5.5 change the prototype of get_current_key leading to 2015-03-30 Hannes Magnusson * PHPC-216: Include our pem files in the pecl archive 2015-03-30 Hannes Magnusson * PHPC-216: Use array(), not [], for PHP5.3 compatibility 2015-03-30 Hannes Magnusson * Split release target into release and packaging 2015-03-30 Hannes Magnusson * PHPC-218: Provision ubuntu image and install & run the test suite 2015-03-30 Hannes Magnusson * No need to sudo, run the scripts as priveleged 2015-03-30 Hannes Magnusson * PHPC-216: PHP5.3 test suite fixes 2015-03-30 Hannes Magnusson * PHPC-217: Include the connection tests in pecl package 2015-03-30 Hannes Magnusson * PHPC-213: Memory alignment issues on FreeBSD 2015-03-30 Hannes Magnusson * Fix stability name according to pecl rules 2015-03-30 Hannes Magnusson * PHPC-216: PHP5.3 test suite fixes 2015-03-27 Hannes Magnusson * Re align 2015-03-27 Hannes Magnusson * PHPC-212: undefined symbol: _mongoc_sasl_set_service_host - patch by remi@php.net 2015-03-26 Hannes Magnusson * Ignore coverage files 2015-03-25 Hannes Magnusson * bump version 2015-03-25 Hannes Magnusson * Merge pull request #28 from jmikola/phpc-201 2015-03-25 Hannes Magnusson * Add 0.3.1 release notes 2015-03-25 Hannes Magnusson * bump version for windows packaging fix 2015-03-25 Hannes Magnusson * PHPC-211: Windows libbson and mongoc config files missing in release archive 2015-03-25 Hannes Magnusson * Link to the docs on php.net 2015-03-25 Hannes Magnusson * Use pecl for installing 2015-03-25 Hannes Magnusson * Bump version 2015-03-25 Hannes Magnusson * Add 0.3.0 release notes 2015-03-25 Hannes Magnusson * Add config.w32 to package.xml 2015-03-25 Hannes Magnusson * Use absolute paths in skipifs too 2015-03-25 Jeremy Mikola * PHPC-201: Rename Result::setTypemap() to setTypeMap() 2015-03-25 Hannes Magnusson * Update bundles for windows fixes 2015-03-25 Hannes Magnusson * PHPC-175: Fix header includes on Windows 2015-03-25 Hannes Magnusson * PHPC-175: Fix build on 32bit 2015-03-25 Hannes Magnusson * PHPC-175: Windows doesn't have these compiler attributes 2015-03-25 Hannes Magnusson * Fix windows bson config 2015-03-25 Hannes Magnusson * IPHPC-176: Copy build templates, add missing file & set build flags 2015-03-25 Hannes Magnusson * Use absolute paths on in tests so they can run easier on windows 2015-03-25 Hannes Magnusson * Absolute path is required to run tests on windows 2015-03-25 Hannes Magnusson * Allow mongoc_init() to not use our mm 2015-03-25 Hannes Magnusson * bump mongoc with windows fixes 2015-03-25 Hannes Magnusson * PHPC-200: Don't set stream initiator when creating client fails 2015-03-25 Hannes Magnusson * PHPC-199: Missing file from mongoc in config.m4 2015-03-24 Hannes Magnusson * Initial win32 attempt 2015-03-24 Hannes Magnusson * Bundle windows configs 2015-03-24 Hannes Magnusson * Improve code coverage 2015-03-23 Hannes Magnusson * Simplify 2015-03-23 Hannes Magnusson * Providing higher init size is worse then providing none 2015-03-23 Hannes Magnusson * Add raises() helper, similar to throws() except for php warnings/notices/deprecated/... 2015-03-24 Hannes Magnusson * ignore mongodb*tgz release files and "failed.txt" from run-tests 2015-03-24 Hannes Magnusson * Bump libbson with timeval fix and mongoc with various sdam fixes 2015-03-23 Jeremy Mikola * Update PECL install instructions for alpha release 2015-03-23 Hannes Magnusson * Include the license file for next release 2015-03-23 Hannes Magnusson * Update naming after PHPC-174 2015-03-23 Hannes Magnusson * Bump version 2015-03-23 Hannes Magnusson * Add 0.2.0 release notes 2015-03-23 Hannes Magnusson * PHPC-174: Rename module registration, constants and so on to mongodb 2015-03-23 Hannes Magnusson * Bump release to 0.2.0-alpha 2015-03-23 Hannes Magnusson * Include the version and config templates 2015-03-23 Hannes Magnusson * Only run our tests as part of release for now 2015-03-23 Hannes Magnusson * PHPC-174: Rename phongo to mongodb 2015-03-23 Hannes Magnusson * PHPC-174: Use consistent extension names for PHP and HHVM drivers 2015-03-23 Hannes Magnusson * PHPC-195: Fix typo and couple of missing incldues 2015-03-23 Hannes Magnusson * PHPC-195: Remove mongoc/bson header file workarounds 2015-03-23 Hannes Magnusson * Test for PHPC-186 2015-03-23 Hannes Magnusson * Remove char * casting, the macro soup leads to incorrect sizeof 2015-03-20 Hannes Magnusson * Fix zts 2015-03-20 Hannes Magnusson * PHPC-183: Add -Wdeclaration-after-statement to --enable-developers-flags 2015-03-20 Hannes Magnusson * PHPC-183: Fix compiler warnings with -Wdeclaration-after-statement 2015-03-20 Hannes Magnusson * PHPC-189: Implement Manager->getServers() 2015-03-20 Hannes Magnusson * PHPC-188: Populate MongoDB\Driver\Server 2015-03-20 Hannes Magnusson * PHPC-24 PHPC-77 PHPC-69 Provide a functioning Server object 2015-03-19 Hannes Magnusson * bump submodule to mongoc 1.2.0-dev - includes sdam stuff 2015-03-18 Hannes Magnusson * PHPC-106: Comment out var_dump() data for now 2015-03-18 Hannes Magnusson * PHPC-106: Enable mongoc SDAM build 2015-03-18 Hannes Magnusson * PHPC-106: Connect asynchronouslyish 2015-03-19 Hannes Magnusson * PHPC-106: Implement the new poll callback 2015-03-18 Hannes Magnusson * In SDAM this is forbidden and throws exception 2015-03-18 Hannes Magnusson * Show the response when the test fails 2015-03-18 Hannes Magnusson * Store the original mongoc_uri_t not just the options bson 2015-03-18 Hannes Magnusson * Add a little tracing love 2015-03-18 Hannes Magnusson * Properly block on socket writes 2015-03-18 Hannes Magnusson * Fix null pointer exception 2015-03-17 Hannes Magnusson * Unhide this 2015-03-17 Jeremy Mikola * Merge pull request #27 2015-03-17 Jeremy Mikola * Return const struct pointers from zval getters 2015-03-17 Jeremy Mikola * PHPC-181: Discard const qualifiers for PHP API 2015-03-17 Jeremy Mikola * PHPC-181: Use const for pointer args where applicable 2015-03-16 Hannes Magnusson * PHPC-180: Fix limited batch import 2015-03-16 Hannes Magnusson * PHPC-180: No need to sleep anything, we get a fresh connection in next test 2015-03-16 Hannes Magnusson * PHPC-180: We now load 1024 users 2015-03-16 Hannes Magnusson * PHPC-180: We now generate 1024 users, only load the first 100 2015-03-16 Hannes Magnusson * PHPC-180: Cache the fixtures 2015-03-16 Hannes Magnusson * Surpress timezone warning by adding it to the ini 2015-03-16 Hannes Magnusson * PHPC-180: Rename constant and pass the cleanup uri explicitly 2015-03-16 Hannes Magnusson * PHPC-180: Replace this Orchestration wrapper with significantly simpler code 2015-03-16 Hannes Magnusson * Use underscore for the id so we can declare them as constants in php 2015-03-16 Hannes Magnusson * Use readable name for the replicaset nodes 2015-03-16 Hannes Magnusson * Minor README updates 2015-03-13 Jeremy Mikola * Merge pull request #26 2015-03-12 Jeremy Mikola * PHPC-168: Implement WriteResult::isAcknowledged() 2015-03-12 Jeremy Mikola * PHPC-170: Don't set write concern on bulk unnecessarily 2015-03-12 Jeremy Mikola * PHPC-177: Include all fields in WriteConcern debug output 2015-03-12 Jeremy Mikola * Remove unnecessary Manager and apply EXPECTF patterns 2015-03-12 Jeremy Mikola * Update Ubuntu's package repository before installing 2015-03-12 Hannes Magnusson * Fixed missing type specifier warning 2015-03-12 Hannes Magnusson * Fix build on MacOSX 2015-03-11 Hannes Magnusson * Its a bulk 2015-03-11 Hannes Magnusson * post release bump 2015-03-11 Hannes Magnusson * Add 0.1.5 release notes 2015-03-11 Hannes Magnusson * MO now actually creates this initial user, use correct subject to fix the X509 tests 2015-03-11 Hannes Magnusson * libbson 1.1.2 & mongoc 1.1.2 2015-03-11 Hannes Magnusson * Add "make help" since I always forget the names 2015-03-05 Hannes Magnusson * PHP5.6 change serveral TLS verfication defaults 2015-03-05 Hannes Magnusson * PHPC-171: SSL Doesn't work in PHP5.6 2015-03-04 Hannes Magnusson * Bump submodules 2015-03-04 Hannes Magnusson * Bump bundled version 2015-03-04 Hannes Magnusson * Fix tests for MongoDB 3.0.0 2015-03-04 Hannes Magnusson * PHPC-129: Fix tests for HIPPO can't throw InvalidArgumentException on argument errors 2015-03-03 Hannes Magnusson * Bump mongoc for PHPC-167 2015-03-03 Hannes Magnusson * Add micro-optimization tip for the future 2015-03-03 Hannes Magnusson * PHPC-129: HIPPO can't throw InvalidArgumentException on argument errors 2015-03-03 Hannes Magnusson * Simplify debug logging logic when running tests standalone 2015-03-03 Hannes Magnusson * PHPC-163: Throw BulkWriteException on BulkWrite failure 2015-02-27 Hannes Magnusson * PHPC-166: Disable (un)serializing of phongo objects 2015-02-20 Hannes Magnusson * PHPC-165: Rename WriteBatch to BulkWrite 2015-02-19 Hannes Magnusson * PHPC-164: Throw MongoDB\Driver\ConnectionTimeoutException 2015-02-19 Hannes Magnusson * This is a Manager, not MongoClient 2015-02-19 Hannes Magnusson * Ignore me. Trim trailing space 2015-02-19 Hannes Magnusson * PHPC-107: Throw ExecutionTimeoutException for maxTimeMs 2015-02-18 Hannes Magnusson * PHPC-159: memleak on failed path resolving 2015-02-18 Hannes Magnusson * PHPC-158: Split queryFlags bitmask option into specific options 2015-02-18 Hannes Magnusson * PHPC-157: Consolidate CommandResult and QueryResult classes 2015-02-18 Hannes Magnusson * PHPC-157: QueryResult and CommandResult are now Result 2015-02-18 Hannes Magnusson * rebase with Result.c 2015-02-18 Hannes Magnusson * PHPC-157: Renamed getResponseDocument() to toArray() 2015-02-18 Hannes Magnusson * PHPC-157: Consolidate CommandResult and QueryResult classes 2015-02-18 Hannes Magnusson * PHPC-157: Remove QueryResult 2015-02-18 Hannes Magnusson * bump mongoc 2015-02-18 Hannes Magnusson * PHPC-155: WriteConcernError->getInfo() can be scalar 2015-02-18 Hannes Magnusson * Add a note about PHPC-72 2015-02-18 Hannes Magnusson * PHPC-154: WriteError can have info field 2015-02-06 Hannes Magnusson * PHPC-153: Rename cursorFlags to queryFlags in Query 2015-02-06 Hannes Magnusson * PHPC-152: Throw MongoDB\Driver\InvalidArgumentException on argument errors 2015-02-06 Hannes Magnusson * Throw our RuntimeException, not SPL 2015-02-02 Hannes Magnusson * post release bump 2015-02-02 Hannes Magnusson * Add 0.1.4 release notes 2015-02-02 Hannes Magnusson * prep for 0.1.4 release 2015-02-02 Hannes Magnusson * PHPC-151: Bump to libbson-1.1.0 and mongoc-1.1.0 and fix build 2015-02-02 Hannes Magnusson * This is a result iterator, not cursor 2015-02-02 Hannes Magnusson * PHPC-149: Iterator holding on to dead results 2015-01-30 Hannes Magnusson * NULLify after destroy and clear 2015-01-30 Hannes Magnusson * 0.1.3 is the current release... 2015-01-29 Hannes Magnusson * PHPC-148: var_dump()ing ObjectID should show the ObjectID 2015-01-29 Hannes Magnusson * PHPC-144: MO first-user changes 2015-01-29 Hannes Magnusson * Make sure we have a document before dumping it 2015-01-29 Hannes Magnusson * Add SSL to the persistance hash 2015-01-28 Hannes Magnusson * Quick note about var_dump()ing the cursor, rather then calling iterator_to_array() 2015-01-28 Hannes Magnusson * PHPC-147: Document the ODS 2015-01-28 Hannes Magnusson * PHPC-146: ReadPreferences swapped 2015-01-28 Hannes Magnusson * PHPC-145: Typo in example, operators need to use single quotes 2015-01-28 Hannes Magnusson * PHPC-143: skip auth tests when the server configuration required isn't available 2015-01-27 Hannes Magnusson * Most of our issues with MO seem to be fixed in master 2015-01-27 Hannes Magnusson * PHPC-142: add 'list-servers' target to enumerate all running MO servers 2015-01-27 Hannes Magnusson * PHPC-140: var_dump()ing WriteConcernError and WriteError 2015-01-27 Hannes Magnusson * PHPC-139: var_dump()ing WriteBatch 2015-01-27 Hannes Magnusson * PHPC-138: var_dump()ing WriteConcern 2015-01-27 Hannes Magnusson * PHPC-138: var_dump()ing ReadPreference 2015-01-26 Hannes Magnusson * PHPC-137: var_dump()ing CursorID should show the Cursor ID 2015-01-09 Hannes Magnusson * simplify 2015-01-09 Hannes Magnusson * PHPC-134: Add the internal results here too 2015-01-09 Hannes Magnusson * PHPC-136: var_dump() CommandResult and QueryResult 2015-01-09 Hannes Magnusson * PHPC-133: var_dump()ing cursor 2015-01-09 Hannes Magnusson * PHPC-135: Fix memory leak var_dump()ing Command 2015-01-09 Hannes Magnusson * PHPC-135: Fix memory leak var_dump()ing Query and add test 2015-01-09 Hannes Magnusson * PHPC-134: Add debug info for WriteResult 2015-01-08 Hannes Magnusson * PHPC-110: Fix segfault on standalone nodes :) 2015-01-08 Hannes Magnusson * PHPC-135: Implement debug handler for Query and Command 2015-01-08 Hannes Magnusson * PHPC-110: Fix segfault when var_dump()ing before connecting 2015-01-07 Hannes Magnusson * PHPC-110: Add var_dump() support for MongoDB\Driver\Manager 2015-01-07 Hannes Magnusson * Revert "PHPC-131: Place the rendered files out of this dir" 2015-01-07 Hannes Magnusson * PHPC-131: Place the rendered files out of this dir 2015-01-07 Hannes Magnusson * PHPC-131: Add jira issue collector 2015-01-06 Hannes Magnusson * PHPC-128: MO presets directory needs to be configurable 2015-01-06 Hannes Magnusson * PHPC-128: if there is no cleanup uri then skipit 2015-01-06 Hannes Magnusson * PHPC-128: Maybe orchestration doesn't like IPs? 2015-01-06 Hannes Magnusson * PHPC-128: more travis debugging 2015-01-06 Hannes Magnusson * PHPC-128: ping should be fast 2015-01-06 Hannes Magnusson * PHPC-130: Update the get_current_key handler to support pre-5.5 2015-01-06 Hannes Magnusson * PHPC-128: Debugging why mo on travis doesn't start 2015-01-06 Hannes Magnusson * PHPC-128: use consistent env variable 2015-01-06 Hannes Magnusson * PHPC-128: Start the nodes using MO 2015-01-06 Hannes Magnusson * PHPC-128: -See if this works better for travis 2015-01-06 Hannes Magnusson * PHPC-128: Fix travis setup 2015-01-06 Hannes Magnusson * PHPC-116: Cursor methods should call their respective iterator function handlers 2015-01-06 Hannes Magnusson * Smiplify cursor/results to prep for PHPC-116 2015-01-06 Hannes Magnusson * We don't need to debug this test anymore 2015-01-06 Hannes Magnusson * PHPC-116: Implement invalidate_current handler to reduce code 2015-01-06 Hannes Magnusson * PHPC-128: Startup the mongodb-org freshly installed mongodb 2015-01-05 Hannes Magnusson * PHPC-128: Set the uri to use on travis 2015-01-05 Hannes Magnusson * PHPC-128: Fix running tests on travis 2015-01-05 Hannes Magnusson * We use corporate coverity now 2015-01-05 Hannes Magnusson * PHP-127: Fix test, use the string stderr, not resource STDERR 2015-01-05 Hannes Magnusson * PHPC-42: Implement root level (full document) ODM style serialization 2015-01-05 Hannes Magnusson * PHPC-125: pointer to out of scope variable :] 2015-01-05 Hannes Magnusson * PHPC-123: Wrong sizeof argument 2015-01-05 Hannes Magnusson * PHPC-124: Buffer not null terminated 2015-01-05 Hannes Magnusson * PHPC-126: Fixed unchecked return 2015-01-02 Hannes Magnusson * PHPC-42: BSON Serialization for classes 2014-12-31 Hannes Magnusson * PHPC-121: Use BSON\Serialize::bsonSerialize() during serialization 2014-12-31 Hannes Magnusson * PHPC-96: Add QueryResult->setTypemap() to overwrite array/object mapping 2014-12-31 Hannes Magnusson * WriteConcernError test 2014-12-31 Hannes Magnusson * initialize correctly 2014-12-31 Hannes Magnusson * fix title 2014-12-31 Hannes Magnusson * PHPC-96 & PHPC-119 call the new bsonUnserialize method and optimize things a little 2014-12-31 Hannes Magnusson * PHPC-120: BSON\toArray should support classmap to unserialize as 2014-12-31 Hannes Magnusson * PHPC-119 && PHPC-49: Create PHP interfaces for BSON (un-)serialization 2014-12-31 Hannes Magnusson * Fix array return 2014-12-30 Hannes Magnusson * No need for these anymore 2014-12-30 Hannes Magnusson * PHPC-118: Use MongoDB\Driver namespace for phongo 2014-12-30 Hannes Magnusson * PHPC-96: Retrieve arrays as custom objects 2014-12-29 Hannes Magnusson * PHPC-117: Simplify bson deserialization code 2014-12-23 Hannes Magnusson * PHPC-50: Implement checking socket state handler 2014-12-23 Hannes Magnusson * latest and gratest libmongoc fixes 2014-12-23 Hannes Magnusson * PHPC-115: Remove now-useless GeneratedId 2014-12-23 Hannes Magnusson * If there is no error, pass null to avoid the type hint 2014-12-22 Hannes Magnusson * PHPC-113: WriteConcernError is just one error, not multiple 2014-12-23 Hannes Magnusson * PHPC-114: Implement WriteConcernError->getMessage() 2014-12-23 Hannes Magnusson * Avoid invalid read when logging from replicaset 2014-12-23 Hannes Magnusson * Simplify cli debugging 2014-12-22 Hannes Magnusson * PHPC-112: Sping up ReplicaSet 2014-12-22 Hannes Magnusson * Bump version 2014-12-22 Hannes Magnusson * The development of this driver is now under the PHPC jira project 2014-12-22 Hannes Magnusson * Bump release version in the docs 2014-12-22 Hannes Magnusson * Add 0.1.3 release notes 2014-12-22 Hannes Magnusson * Fix paths to root dir .phar 2014-12-22 Hannes Magnusson * Add new files to the packager 2014-12-22 Hannes Magnusson * Update composer after the repo renaming 2014-12-22 Hannes Magnusson * mongoc requires newer libbson now 2014-12-22 Hannes Magnusson * bump mongoc 2014-12-22 Hannes Magnusson * rename the Mongo Orchestration name to 'mo' 2014-12-22 Hannes Magnusson * MO PR#161 includes fixes from 155, and adds ssl auth support 2014-12-22 Hannes Magnusson * PHPC-33: Implement X509 support via PHP streams 2014-12-22 Hannes Magnusson * Fix typo in persistent hash 2014-12-19 Jeremy Mikola * Add Apache 2 license 2014-12-19 Hannes Magnusson * PHPC-33: Add tests for X509 2014-12-19 Hannes Magnusson * bump mongoc 2014-12-19 Hannes Magnusson * PHPC-104: Throw MongoDB\AuthenticationException on auth failure 2014-12-19 Hannes Magnusson * Fix test titles 2014-12-18 Hannes Magnusson * bump mongoc 2014-12-18 Hannes Magnusson * Remove useless stuff 2014-12-18 Hannes Magnusson * Workaround https://github.com/10gen/mongo-orchestration/issues/154 2014-12-18 Hannes Magnusson * PHPC-31: Implement PLAIN authentication via PHP streams 2014-12-18 Hannes Magnusson * PHPC-31: Test for PLAIN authentication mechanism 2014-12-18 Hannes Magnusson * PHPC-45: Orchestrate LDAP/PLAIN servers 2014-12-18 Hannes Magnusson * PHPC-45: Orchestarte PLAIN/LDAP authentication mechanism 2014-12-18 Hannes Magnusson * PHPC-103: Virtualize OpenLDAP server using CentOS 2014-12-18 Hannes Magnusson * Reorganize Vagrantfile to make room for more images 2014-12-18 Hannes Magnusson * PHPC-2: Persist connection by the dsn 2014-12-18 Hannes Magnusson * PHPC-101: throw MongoDB\DuplicateKeyException 2014-12-18 Hannes Magnusson * Enable test and fixit 2014-12-17 Hannes Magnusson * PHON-85: Improve test 2014-12-17 Hannes Magnusson * ignore ctags and local vimrc 2014-12-17 Hannes Magnusson * PHON-99: Add & Implement SSLConnectionException 2014-12-17 Hannes Magnusson * PHON-31: Add stream context options 2014-12-17 Hannes Magnusson * PHON-100: Implement connectiontimeoutms 2014-12-17 Hannes Magnusson * PHON-31: Do not overload the stream_initiator with tsrm, we want it for stream context later 2014-12-17 Hannes Magnusson * PHON-98: Implement and properly throw MongoDB\ConnectionException 2014-12-17 Hannes Magnusson * PHON-97: Add MongoDB\RuntimeException 2014-12-17 Hannes Magnusson * PHON-96: Create MongoDB\Exception interface 2014-12-16 Hannes Magnusson * PHON-22: New test to verify standard authentication 2014-12-16 Hannes Magnusson * PHON-23: Add test for connecting to SSL server 2014-12-16 Hannes Magnusson * PHON-6: Split normal SSL and X509 servers 2014-12-16 Hannes Magnusson * PHON-3: Orchestrate standard authentication 2014-12-16 Hannes Magnusson * PHON-6: Orchestrate SSL and X509 2014-12-16 Hannes Magnusson * PHON-7: Trivial Monog Orchestration abstraction 2014-12-16 Hannes Magnusson * exit on failure - and include a greppable error 2014-12-16 Hannes Magnusson * PHON-92: Create standalone MongoDB server 2014-12-16 Hannes Magnusson * PHONG-91: Yes to all questions when installing mongodb 2014-12-16 Hannes Magnusson * PHON-91: Use the vm by default, allow it to be overridden by the environment variable 2014-12-16 Hannes Magnusson * PHON-5: Whopsy, missing file for startting servers hidden by gitignore 2014-12-16 Hannes Magnusson * PHON-91: Use Vagrant to virtualise mongod 2014-12-16 Hannes Magnusson * return true on success 2014-12-15 Hannes Magnusson * Use the MONGODB_URI constant 2014-12-15 Hannes Magnusson * PHON-5: Use Mongo Orchestration to manage MongoDB servers 2014-12-15 Hannes Magnusson * Seperate code from functions 2014-12-16 Hannes Magnusson * remove hyperbole description 2014-12-15 Jeremy Mikola * Merge pull request #24 from hannesvdvreken/master 2014-12-15 Hannes Van De Vreken * Fixed spelling mistake 2014-12-12 Hannes Magnusson * PHP-1337: Implement killing a MongoDB Cursor 2014-12-12 Hannes Magnusson * PHP-1336: Use Cursor->getId(), not Cursor->getCursorId() 2014-12-12 Hannes Magnusson * Call the bson module init 2014-12-12 Hannes Magnusson * PHP-1338: There is actually no DBRef BSON type, its a convention 2014-12-12 Hannes Magnusson * PHP-1181: Improve coverage for BSON\UTCDateTime 2014-12-12 Hannes Magnusson * PHP-1181: Improve coverage for BSON\Timestamp 2014-12-12 Hannes Magnusson * PHP-1181: Improve coverage for BSON\Regex 2014-12-12 Hannes Magnusson * PHP-1181: Improve coverage for BSON\ObjectID 2014-12-12 Hannes Magnusson * Improve exception testing 2014-12-12 Hannes Magnusson * PHP-1181: uhm.. This is minkey test! 2014-12-12 Hannes Magnusson * PHP-1181: Increse BSON\Binary testcoverage 2014-12-12 Jeremy Mikola * Fix composer update and test execution for userland library 2014-12-12 Hannes Magnusson * Proper librt linking on platforms that need it 2014-12-12 Jeremy Mikola * Reformat composer.json and remove redundant autoload block 2014-12-12 Hannes Magnusson * Skip phpunit tests for now, its a bit of an chicken-and-egg issue 2014-12-12 Hannes Magnusson * Update links after moving the repo to 10gen-labs from bjori 2014-12-11 Hannes Magnusson * Fix instructions 2014-12-11 Hannes Magnusson * PHP-1334: Fix build on MacOSX: Don't hardcode librt, we already conditionally check for it 2014-12-10 Jeremy Mikola * Require composer deps before test tasks 2014-12-10 Jeremy Mikola * Use CRUD's PHPUnit config when running tests 2014-12-10 Jeremy Mikola * Use composer update instead of install 2014-12-09 Hannes Magnusson * I have no idea what made me make BSON\Pool 2014-12-09 Hannes Magnusson * Run the phongo-crud tests to 2014-12-09 Hannes Magnusson * PHP-1324: Embed phongo-crud tests under 'testunit' and 'testall' targets 2014-12-09 Hannes Magnusson * Add the phongo-crud to the composer autoloader 2014-12-09 Hannes Magnusson * bump libmongoc without ssl=prefer 2014-12-09 Hannes Magnusson * PHP-1329: Remove ssl=prefer option 2014-12-09 Hannes Magnusson * Fetch phongo-crud to share its tests 2014-12-09 Hannes Magnusson * Search for composer.phar too for those not with it globally installed 2014-12-09 Hannes Magnusson * PHP-1323: Document install instructions from vcs 2014-12-08 Hannes Magnusson * Add documentation build and release targets 2014-12-08 Hannes Magnusson * Bump install instructions 2014-12-08 Hannes Magnusson * Add couple of more reminders 2014-12-08 Hannes Magnusson * Bump version 2014-12-08 Hannes Magnusson * Fix argument passing :] 2014-12-08 Hannes Magnusson * Add release notes 2014-12-08 Hannes Magnusson * PHP-1322: More renaming 2014-12-08 Hannes Magnusson * PHP-1322 Rename count methods in WriteResults 2014-12-08 Hannes Magnusson * PHP-1320: $batch->update() fails when replacing entire document 2014-12-08 Hannes Magnusson * PHP-1319: Convert this into normalish cursor 2014-12-05 Hannes Magnusson * PHP-1319: Implement command cursors 2014-12-08 Hannes Magnusson * Add tracing to mongoc 2014-12-05 Hannes Magnusson * We are throwing exception here, doesn't matter if we are assigning return value 2014-12-05 Hannes Magnusson * Throw exception on failure 2014-12-05 Hannes Magnusson * Make phongo_throw_exception variadic to improve error messages 2014-12-05 Hannes Magnusson * Fix reference counting of nested bson objects 2014-12-04 Hannes Magnusson * Bump version 2014-12-04 Hannes Magnusson * Commit the release notes 2014-12-03 Hannes Magnusson * Take the release notes from the release file 2014-12-03 Hannes Magnusson * Lets not actually tag automatically, just ask politely 2014-12-03 Hannes Magnusson * Whopsy, we need $$ to read the output 2014-12-03 Hannes Magnusson * Update toc and run syntax highlitghting automatically 2014-12-03 Hannes Magnusson * Add command docs 2014-12-03 Hannes Magnusson * WS 2014-12-03 Hannes Magnusson * Initial documentation 2014-12-03 Hannes Magnusson * Move docs to old-docs making way for actual documentation 2014-12-03 Hannes Magnusson * Remove unused command 2014-12-02 Hannes Magnusson * Integer IDs can also be int32 2014-12-02 Hannes Magnusson * Fix 32bit builds 2014-12-02 Hannes Magnusson * PHP-1195: Integers are now represented as int32, as long as they fit 2014-12-02 Hannes Magnusson * Differenciate the connection type by the SSL option 2014-12-02 Hannes Magnusson * Bail out when we cannot connect to the server! 2014-12-02 Hannes Magnusson * PHP-1195: Error out on 32bit platforms if we cannot represent the int 2014-12-02 Hannes Magnusson * PHP-1195: Remove Int32 and Int64 classess 2014-12-02 Hannes Magnusson * Remove misterious BSON\Log class 2014-12-02 Hannes Magnusson * bump libmongoc with ssl fix 2014-12-02 Hannes Magnusson * PHP-1175: Add Support for SSL=true and SSL=prefer 2014-12-02 Hannes Magnusson * PHP-1175: Compile against OpenSSL 2014-12-01 Hannes Magnusson * Improve API consistency between WriteConcern and ReadPreference 2014-11-26 Hannes Magnusson * PHP-1296: Implement WriteConcerns 2014-11-26 Hannes Magnusson * PHP-1295: Memory leak when generating ID for inserts 2014-11-26 Hannes Magnusson * PHP-1294: Emtpy Query Result should still return QueryResult 2014-11-26 Hannes Magnusson * Add an example "document browser" 2014-11-26 Hannes Magnusson * PHP-1293: Writing all debug info is not a good default 2014-11-26 Hannes Magnusson * WS 2014-11-26 Hannes Magnusson * We only allow object/array here, not need for this extra code 2014-11-26 Hannes Magnusson * PHP-1292: BSON Arrays should be... PHP Arrays 2014-11-26 Hannes Magnusson * PHP-1291: memleak when serializing nested objects/array 2014-11-26 Hannes Magnusson * Initialize to NULL 2014-11-26 Hannes Magnusson * Enable the corrupt BSON handler for debugging 2014-11-26 Hannes Magnusson * Add missing arginfo for the BSON encoding functions 2014-11-25 Hannes Magnusson * List commits per release in the RELEASE file 2014-11-25 Hannes Magnusson * Bump version 2014-11-26 Hannes Magnusson * Update README for current situation 2014-11-25 Hannes Magnusson * Ignore the run-tests php.ini 2014-11-25 Hannes Magnusson * We haven't executed the test target yet! 2014-11-25 Hannes Magnusson * Fix coverage build 2014-11-25 Hannes Magnusson * Create the tag at the end of making the release ball 2014-11-25 Hannes Magnusson * Compiler warnings 2014-11-25 Hannes Magnusson * Running the tests is of course part of a release 2014-11-25 Hannes Magnusson * Ignore generated files 2014-11-25 Hannes Magnusson * Expose version constants and stability 2014-11-25 Hannes Magnusson * Fix version number 2014-11-25 Hannes Magnusson * Get the release number from the module 2014-11-25 Hannes Magnusson * Update travis for build system changes 2014-11-25 Hannes Magnusson * Fix building out of root 2014-11-25 Hannes Magnusson * Generate package.xml and release archive 2014-11-25 Hannes Magnusson * Don't Move this to a dedicated patch target 2014-11-25 Hannes Magnusson * Add CREDITS 2014-11-25 Hannes Magnusson * Add a target to generate a ChangeLog 2014-11-25 Hannes Magnusson * Add a custom build target dependency 2014-11-25 Hannes Magnusson * This seems to be the conventional wisdom setting ulimit on travis 2014-11-25 Hannes Magnusson * PHP-1289: Automatically apply our required patches 2014-11-24 Hannes Magnusson * No longer needed 2014-11-24 Hannes Magnusson * PHP-1289: Revamp the build system to embed libmongoc, libbson and yajl 2014-11-24 Hannes Magnusson * Set ulimit before our trap 2014-11-24 Hannes Magnusson * Don't include libbson or libmongoc in the coverage report 2014-11-24 Hannes Magnusson * Fixed CID-60852: Pointer to local outside scope 2014-11-24 Hannes Magnusson * This is the master branch 2014-11-24 Hannes Magnusson * Fix ZTS - and all the segfaults 2014-11-21 Hannes Magnusson * Attempt to fix stream closing in zts 2014-11-21 Hannes Magnusson * Fix zts builds 2014-11-21 Hannes Magnusson * Use my libmongoc fork for now 2014-11-21 Hannes Magnusson * bump libmongoc in my fork 2014-11-21 Hannes Magnusson * Fixed various memory leaks and compiler warnings 2014-11-21 Hannes Magnusson * PHP-1189: Implement BSON regex type 2014-11-21 Hannes Magnusson * Fixed couple of constify, and renamed a functino to be consistent with'em all 2014-11-11 Jeremy Mikola * PHP-1189: BSON Regex type 2014-11-21 Hannes Magnusson * PHP-1187: Implement BSON binary type 2014-11-21 Hannes Magnusson * Move the helpers up rather then in the middle of the vtable 2014-11-21 Hannes Magnusson * Fix some compiler warnings: (de-)constify 2014-11-20 Hannes Magnusson * bump libbson 2014-11-20 Hannes Magnusson * PHP-1188: Implement BSON code and code with scope types 2014-11-20 Hannes Magnusson * Fixed zts macros 2014-11-20 Hannes Magnusson * PHP-1191: Implement BSON timestamp type 2014-11-20 Hannes Magnusson * Fix arginfo and proto 2014-11-20 Hannes Magnusson * Fix test: Whoopsy. Missed the DONE section 2014-11-20 Hannes Magnusson * PHP-1194: Implement BSON MaxKey and MinKey types 2014-11-20 Hannes Magnusson * Bump libmongoc, and temporary switch to my fork with the needed patches 2014-11-20 Hannes Magnusson * Fixed PHP-1174: Implement WriteBatch::count() 2014-11-19 Hannes Magnusson * PHP-1190: Implement BSON\UTCDateTime 2014-11-19 Hannes Magnusson * PHP-1185: Add more Cursor related methods 2014-11-19 Hannes Magnusson * Fixed PHP-1185: Implement Cursor class 2014-11-19 Hannes Magnusson * PHP-1183: Implement default Iterator class for QueryResult & CommandResult 2014-11-19 Hannes Magnusson * Avoid compiler warnings 2014-11-19 Hannes Magnusson * Fixed PHP-1232: Implement the TODO 2014-11-19 Hannes Magnusson * Do not test the error messages from the server 2014-11-19 Hannes Magnusson * Tell PHP this is indeed an exposed stream that it doesn't have to worry about 2014-11-19 Hannes Magnusson * Fix memory leak when splitting a ns 2014-11-18 Hannes Magnusson * Make sure we have something to free 2014-11-04 Jeremy Mikola * Merge pull request #22 from hannesvdvreken/patch-1 2014-11-03 Hannes Van De Vreken * Typo in readme? "admit" instead of "admin" 2014-10-20 Hannes Magnusson * Merge pull request #21 from christkv/master 2014-10-20 Christian Kvalheim * Fixed build for OSX and llvm 2014-10-19 Jeremy Mikola * Rewrite README and document install/test process 2014-10-17 Jeremy Mikola * Merge pull request #18 from bjori/php1236-test-fixtures 2014-10-16 Jeremy Mikola * PHP-1180: Create make target to install Composer dependencies (for tests) 2014-08-05 Jeremy Mikola * Functional tests for sorted queries 2014-08-05 Jeremy Mikola * Use Faker to create user data fixtures 2014-08-05 Jeremy Mikola * Use require_once in skip test includes 2014-08-06 Jeremy Mikola * Use "phongo_test" as default test database 2014-08-06 Jeremy Mikola * Use preg_replace() for generating collection name from test file 2014-08-05 Jeremy Mikola * Clean up hex_dump() source and add citation 2014-10-03 Jeremy Mikola * Merge pull request #20 2014-10-03 Jeremy Mikola * PHP-1173: Use string "majority" for WriteConcern::MAJORITY 2014-10-03 Jeremy Mikola * Remove unused class properties in WriteConcern 2014-10-02 Jeremy Mikola * Merge pull request #19 from bjori/php1230-take-two 2014-10-02 Jeremy Mikola * PHP-1230: Clean up WriteResult property storage on WriteException 2014-09-30 Jeremy Mikola * Merge branch 'dry-run' 2014-09-30 Jeremy Mikola * Merge pull request #16 2014-09-29 Jeremy Mikola * Use correct return types for WriteResult-related init functions 2014-09-25 Jeremy Mikola * PHP-1142: Dump WriteResult object in write tests 2014-09-25 Jeremy Mikola * PHP-1142: Support upserted ids in WriteResult 2014-09-25 Jeremy Mikola * PHP-1142: Implement WriteResult getter for meta information 2014-09-25 Jeremy Mikola * PHP-1142: Memory cleanup and getters for WriteResult error zvals 2014-09-25 Jeremy Mikola * Fix tab indentation for generated C code 2014-09-24 Jeremy Mikola * Throw WriteException on failed write ops 2014-09-24 Jeremy Mikola * PHP-1230: Implement WriteException class 2014-09-24 Jeremy Mikola * Return exceptions after throwing in case we need to modify them 2014-09-24 Jeremy Mikola * PHP-1142: Init WriteError and WriteConcernError arrays for WriteResult 2014-09-24 Jeremy Mikola * PHP-1171: Move WriteConcernError init function to php_phongo.c 2014-09-24 Jeremy Mikola * PHP-1172: Implement WriteError class 2014-09-24 Jeremy Mikola * Fix typo in constant name 2014-09-23 Jeremy Mikola * Ensure libmongoc structs get freed in WriteBatch and WriteConcern 2014-09-18 Jeremy Mikola * Merge pull request #14 from bjori/php-1171-writeconcernerror 2014-09-17 Jeremy Mikola * PHP-1171: Implement WriteConcernError class 2014-09-05 Jeremy Mikola * Merge pull request #13 from bjori/php-1068 2014-09-05 Jeremy Mikola * PHP-1068: Test that CommandResult is iterable 2014-08-25 Jeremy Mikola * Merge pull request #12 2014-08-21 Jeremy Mikola * Always wrap query filter with $query modifier 2014-08-21 Jeremy Mikola * Use array helpers instead of hash iteration in Query option parsing 2014-08-21 Jeremy Mikola * Error if phongo_query_init() filter isn't array or object 2014-08-14 Jeremy Mikola * Use ZEND_STRS() when passing string/size arguments 2014-08-14 Jeremy Mikola * Fix setting of zvals with zend_hash_update() when constructing query 2014-08-11 Jeremy Mikola * Update tests for revised Query constructor API 2014-08-11 Jeremy Mikola * Change Query constructor args based on CRUD API spec 2014-08-11 Jeremy Mikola * Rename query document field in query struct 2014-08-22 Hannes Magnusson * bump submodules 2014-08-20 Hannes Magnusson * WS 2014-08-20 Hannes Magnusson * Fix segfault when no namespace is passed 2014-08-20 Hannes Magnusson * BSON: Fix serializing arrays inside of objects 2014-08-13 Hannes Magnusson * Move BSON encode/decode stuff into BSON namespace 2014-08-13 Hannes Magnusson * Enable a waterfall of compiler instructions for libbson and mongoc 2014-08-13 Hannes Magnusson * Supress the initialization output 2014-08-12 Hannes Magnusson * These dirs are required for all normal 'make' targets 2014-08-12 Hannes Magnusson * Overwrite the path to libbson that should be linked against 2014-08-12 Hannes Magnusson * debugging travis 2014-08-12 Hannes Magnusson * Build against bundled.. just not mongoc bundled 2014-08-12 Hannes Magnusson * Remove empty dir since there is nothing to make there 2014-08-12 Hannes Magnusson * Hack around mongo-c-driver not allowing us specify libbson location 2014-08-12 Hannes Magnusson * Link against libbson and make it available to mongo-c-driver 2014-08-12 Hannes Magnusson * Missed a file 2014-08-12 Hannes Magnusson * We submodule these now and automatically build it 2014-08-12 Hannes Magnusson * submodule mongo-c-driver and libbson and build it into phongo 2014-08-08 Hannes Magnusson * Fix zts 2014-08-08 Hannes Magnusson * Reduce mongoc stuff we compile and install 2014-08-08 Hannes Magnusson * Link against libmongoc-priv so we can go into the gory details 2014-08-06 Hannes Magnusson * Implement BSON\ObjectID properly 2014-08-04 Hannes Magnusson * Fix installing lcov 2014-07-31 Hannes Magnusson * Only skip it on travis 2014-07-30 Hannes Magnusson * CID-24876: Actually check for the return value and raise a warning now 2014-07-30 Hannes Magnusson * Simplify logging domain 2014-07-30 Hannes Magnusson * CID-39604: Fixed possible null dereferencing 2014-07-30 Hannes Magnusson * s/executeWrite/executeWriteBatch/g as the class is called WriteBatch 2014-07-30 Hannes Magnusson * Only collect and return the _id if requested - and never $this 2014-07-30 Hannes Magnusson * optimize BSON class' and allow ObjectID to have other then _id key 2014-07-30 Hannes Magnusson * Sprinkly tad bit more logging and fix coupleof protos 2014-07-30 Hannes Magnusson * Add json_to_bson() function 2014-07-30 Hannes Magnusson * Try properly to read as much data as requested 2014-07-30 Hannes Magnusson * Copy the oid 2014-07-30 Hannes Magnusson * Make BSON types implement BSON\Type interface 2014-07-22 Hannes Magnusson * Remove dirty hack and add a more dirty hack to fetch usable run-tests 2014-07-22 Hannes Magnusson * make sure a empty file doesn't break our build 2014-07-22 Hannes Magnusson * Don't run tests under valgrind on travis... bug in valgrind+libmongoc 2014-07-21 Hannes Magnusson * Install libmongoc using mci generated packages 2014-07-21 Hannes Magnusson * Fix bson buffer 2014-07-21 Hannes Magnusson * Implement WriteConcern 2014-07-21 Hannes Magnusson * new tests 2014-07-21 Hannes Magnusson * Fix zts 2014-07-21 Hannes Magnusson * Fix constant generator & regenerate 2014-07-21 Hannes Magnusson * Implement readPreferences 2014-07-21 Hannes Magnusson * Improve ignore paths 2014-07-21 Hannes Magnusson * Travis CI fixes 2014-07-19 Hannes Magnusson * fix path to ignore 2014-07-19 Hannes Magnusson * fix zts 2014-07-18 Hannes Magnusson * Add __toString() for ObjectID 2014-07-19 Hannes Magnusson * Returned generate _id when adding objects to batches 2014-07-19 Hannes Magnusson * Improve example 2014-07-19 Hannes Magnusson * Add ObjectID support 2014-07-19 Hannes Magnusson * Forgotten things for new classes 2014-07-18 Hannes Magnusson * Fix \0 in property names (private props, ...) 2014-07-18 Hannes Magnusson * Add the ability to automatically generate _id 2014-07-17 Hannes Magnusson * Better way to run the tests through valgrind 2014-07-18 Hannes Magnusson * Missing new class 2014-07-18 Hannes Magnusson * Add BSON objects and move generated classes into its own folders 2014-07-18 Jeremy Mikola * Only use GeneratedId for upserts, not inserts 2014-07-18 Jeremy Mikola * Replace createFromServers() factory method with getServers() 2014-07-17 Jeremy Mikola * Create WriteConcern value object 2014-07-17 Jeremy Mikola * Merge pull request #10 from bjori/make-testclean 2014-07-17 Jeremy Mikola * Replace clean-tests.sh with make target 2014-07-17 Hannes Magnusson * Run the tests under valgrind on travis 2014-07-17 Jeremy Mikola * Revise Manager::executeUpdate() error test 2014-07-17 Jeremy Mikola * Fix warning for bson_uint32_to_string() string pointer arg 2014-07-17 Jeremy Mikola * Shell script to clean up leftover test files 2014-07-16 Hannes Magnusson * Fix constants value 2014-07-16 Hannes Magnusson * Regenerate after coverity fixes 2014-07-17 Hannes Magnusson * Ignore the bundled zval array helper header 2014-07-16 Hannes Magnusson * tralalalllala. It really needs to be dedicated branch 2014-07-16 Hannes Magnusson * make clean first as it had already been built by compile.sh 2014-07-16 Hannes Magnusson * Get coverity to build the dry-run branch automatically 2014-07-16 Hannes Magnusson * I just learned about trap 2014-07-16 Hannes Magnusson * CID-24870: Unchecked return value from library 2014-07-16 Hannes Magnusson * CID-24872: Comment out not-yet-implemented code 2014-07-16 Hannes Magnusson * CID-24873: Unreachable code whoopsy! 2014-07-16 Hannes Magnusson * CID-24875: Fix uninitialized variable 2014-07-16 Hannes Magnusson * Avoid a deadcode warning from coverity 2014-07-16 Hannes Magnusson * Coverity link 2014-07-16 Hannes Magnusson * Update API listing 2014-07-16 Hannes Magnusson * Who doesn't like badges 2014-07-16 Hannes Magnusson * skip on travis.. 2014-07-16 Hannes Magnusson * Fix constants value 2014-07-16 Hannes Magnusson * Add a new none flag 2014-07-15 Hannes Magnusson * Generate all the C objects based on the PHP code 2014-07-15 Hannes Magnusson * Add the actual implementation into the PHP API docs 2014-07-15 Hannes Magnusson * Add a compare_objects handler for Server objects and always try to have a mongoc_host_t for it 2014-07-15 Hannes Magnusson * CS 2014-07-15 Hannes Magnusson * No need for this hack anymore 2014-07-15 Hannes Magnusson * We want latest and greatest mongodb 2014-07-15 Hannes Magnusson * Use bson_uint32_to_string() rather the spprintf() 2014-07-15 Hannes Magnusson * Fix the remaining tests 2014-07-15 Hannes Magnusson * Get tests to pass 2014-07-15 Hannes Magnusson * fix test 2014-07-14 Hannes Magnusson * fix tests 2014-07-14 Hannes Magnusson * whopsy 2014-07-14 Hannes Magnusson * revert accidental removal 2014-07-14 Hannes Magnusson * Revert accidental removal 2014-07-14 Hannes Magnusson * Extract the hint from the cursor 2014-07-14 Hannes Magnusson * No longer needed 2014-07-14 Hannes Magnusson * api changes 2014-07-14 Hannes Magnusson * Easier to maintain in a single file 2014-07-14 Hannes Magnusson * Regenerated 2014-07-14 Hannes Magnusson * Update bootsrapper 2014-07-14 Hannes Magnusson * Fix classname 2014-07-14 Hannes Magnusson * Add a zval array helper 2014-07-14 Hannes Magnusson * Add support for delete options 2014-07-09 Jeremy Mikola * PHP-1136: Allow custom cursor classes from command/query results 2014-07-09 Jeremy Mikola * Remove *.php from gitignore 2014-07-11 Hannes Magnusson * Initial Server implementation (as read-only object..) 2014-07-11 Hannes Magnusson * Fix test 2014-07-11 Hannes Magnusson * We have to save the results so they don't get posted to qa.php.net 2014-07-11 Hannes Magnusson * pretend object_properties_init() exists on PHP5.3 2014-07-11 Hannes Magnusson * Only run coveralls on success 2014-07-10 Hannes Magnusson * Fix zts 2014-07-10 Hannes Magnusson * Install libbson and libmongoc masters rather then releases 2014-07-10 Hannes Magnusson * Cosmetics and remove dead function 2014-07-10 Hannes Magnusson * Remove batch hacks & added single_[insert|update|delete] 2014-07-09 Hannes Magnusson * Touch up WriteResult as return value 2014-07-09 Hannes Magnusson * Fixed PHP-1138: Use Zend MM for libbson 2014-07-09 Hannes Magnusson * Fixed PHP-1137: Removed ugly private API hacks 2014-07-08 Hannes Magnusson * Return correct Result class 2014-07-08 Hannes Magnusson * Initialize optional arg as NULL 2014-07-08 Hannes Magnusson * Fix tests and push getServer() info down 2014-07-08 Hannes Magnusson * Remove no-longer valid classes 2014-07-08 Hannes Magnusson * Add ReadPreferences and full Query support 2014-07-08 Jeremy Mikola * Consolidate write result classes into WriteResult 2014-07-07 Jeremy Mikola * Add phpt files to gitignore 2014-07-07 Jeremy Mikola * Tests for constants and Server/Manager execute methods 2014-07-08 Hannes Magnusson * Fix calling continue in global scope 2014-07-08 Hannes Magnusson * Return MongoDB\Result when executing commands too 2014-07-03 Hannes Magnusson * print out our configure output 2014-07-03 Hannes Magnusson * Batch test and fix skipping test during cleanup phase 2014-07-03 Hannes Magnusson * Dead code 2014-07-03 Hannes Magnusson * Imlement batch execution 2014-07-03 Hannes Magnusson * FIXME: libmongoc workarounds... 2014-07-03 Hannes Magnusson * Fix type hint 2014-07-03 Hannes Magnusson * Missing batch ctor 2014-07-03 Hannes Magnusson * avoid bogus files showing up on coverage reports 2014-07-02 Hannes Magnusson * Simplify Batch interface 2014-07-02 Hannes Magnusson * See if this has any affect on coveralls.. 2014-07-02 Hannes Magnusson * we need newer lcov then howmany decades old the one in repo is 2014-07-02 Hannes Magnusson * Missing lcov on travis for coverage 2014-07-02 Hannes Magnusson * Bump to latest release 2014-07-02 Hannes Magnusson * guess the directory needs to exist 2014-07-02 Hannes Magnusson * Compile libmongoc from the src/ dir so we can steal the private header 2014-07-02 Hannes Magnusson * Rename it to _default so we don't conflict the actual defaults 2014-07-02 Hannes Magnusson * Make sure spl is loaded before we are in static builds 2014-07-02 Hannes Magnusson * fix zts 2014-07-02 Hannes Magnusson * Renamed error const 2014-07-02 Hannes Magnusson * Some zts fixes 2014-07-02 Hannes Magnusson * Fix building as a static extension 2014-07-02 Hannes Magnusson * ignore test files 2014-07-02 Hannes Magnusson * Simplify testing 2014-07-02 Hannes Magnusson * Better logging 2014-07-01 Hannes Magnusson * Return a result object and implement an iterator for it 2014-06-30 Hannes Magnusson * remove useless code 2014-06-30 Hannes Magnusson * rly? 2014-06-30 Hannes Magnusson * New class 2014-06-30 Hannes Magnusson * semicolon 2014-06-30 Hannes Magnusson * make it final and update to match the docs 2014-06-30 Hannes Magnusson * fqd 2014-06-30 Hannes Magnusson * wip query 2014-06-27 Hannes Magnusson * wip 2014-06-30 Hannes Magnusson * Add a generic result object that can be iterated over via iteratoraggregate 2014-06-30 Hannes Magnusson * This cursor needs a firstBatch, just like the CommandCursor 2014-06-27 Hannes Magnusson * fixed warnings and alloc 2014-06-27 Hannes Magnusson * blah 2014-06-27 Hannes Magnusson * wip 2014-06-26 Hannes Magnusson * Added logging to files and command executing 2014-06-24 Hannes Magnusson * Create a mongoc_client from URI 2014-06-24 Hannes Magnusson * More cruft for objects 2014-06-24 Hannes Magnusson * Remove duplicate include 2014-06-24 Hannes Magnusson * phongo api... 2014-06-24 Hannes Magnusson * Register default object handlers 2014-06-24 Hannes Magnusson * Add runtime error domain enum - and a wrapper to get exception type 2014-06-20 Hannes Magnusson * Fix zts 2014-06-20 Hannes Magnusson * Lets not enable developers flags on travis until we get a valid build first :) 2014-06-19 Hannes Magnusson * Add BSON tests 2014-06-18 Hannes Magnusson * Initial BSON implementation 2014-06-20 Hannes Magnusson * Fix include path 2014-06-20 Hannes Magnusson * Quick hack to install libmongoc on travis 2014-06-20 Hannes Magnusson * Add travis and coveralls support 2014-06-19 Hannes Magnusson * Update description per review from Jeremy 2014-06-19 Hannes Magnusson * Implement basics of phongo_exception_from_mongoc_domain() 2014-06-18 Hannes Magnusson * Implement the phongo_exception_from_phongo_domain() function 2014-06-18 Hannes Magnusson * Isolate all PHP compatability stuff into its own file 2014-06-18 Hannes Magnusson * PHP Extension CRUFT for phongo 2014-06-17 Hannes Magnusson * Add config.m4 2014-06-18 Hannes Magnusson * Skeleton implementation of the userland classes/methods 2014-06-18 Hannes Magnusson * Add .gitignore 2014-06-19 Hannes Magnusson * Add descriptions 2014-06-19 Hannes Magnusson * Merge pull request #5 from bjori/fix-query-flags 2014-06-19 Jeremy Mikola * Fix bit values for query flags 2014-06-17 Hannes Magnusson * Merge pull request #3 from bjori/docblocks 2014-06-16 Hannes Magnusson * Change some @see into @param or @param and add some descriptions 2014-06-16 Hannes Magnusson * Lets not start out with complicated zpp... 2014-06-16 Hannes Magnusson * Fix return value 2014-06-16 Hannes Magnusson * Fix docblock param order 2014-06-16 Hannes Magnusson * Add a bootstrapping file that includes all other files 2014-06-16 Hannes Magnusson * Pass through php -l 2014-06-16 Jeremy Mikola * Merge pull request #2 from bjori/split-classes 2014-06-13 Jeremy Mikola * Specity write options in execute methods, not batch constructors 2014-06-13 Jeremy Mikola * Command execution takes a database name, not a namespace 2014-06-13 Jeremy Mikola * Add cursor flag constants 2014-06-12 Jeremy Mikola * Implement review feedback 2014-06-12 Jeremy Mikola * Split API classes and interfaces 2014-05-14 Derick Rethans * Fixed unintialized variable 2014-05-13 Hannes Magnusson * The CRUD examples are now multiple separate files 2014-05-13 Hannes Magnusson * Merge pull request #1 from bjori/split-crud 2014-05-13 Jeremy Mikola * Query constructor should take query object, not just criteria 2014-05-13 Jeremy Mikola * Use value objects and make QueryResult IteratorAggregate 2014-05-13 Jeremy Mikola * Split and modify CRUD examples 2014-05-06 Hannes Magnusson * Add basic .gitignore 2014-05-06 Hannes Magnusson * Initial draft of suggested API 2014-05-06 Hannes Magnusson * Example of a wishful API 2014-05-06 Hannes Magnusson * Initial commit mongodb-1.1.5/LICENSE0000664000175000017500000002613712673034026014024 0ustar jmikolajmikola Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. mongodb-1.1.5/Makefile.frag0000664000175000017500000001155212673034026015370 0ustar jmikolajmikola.PHONY: coverage testclean ChangeLog RELEASE package package.xml docs DATE=`date +%Y-%m-%d--%H-%M-%S` MONGODB_VERSION=$(shell php -n -dextension=modules/mongodb.so -r 'echo MONGODB_VERSION;') MONGODB_MINOR=$(shell echo $(MONGODB_VERSION) | cut -d. -f1,2) MONGODB_STABILITY=$(shell php -n -dextension=modules/mongodb.so -r 'echo MONGODB_STABILITY;') LIB_PATH=vendor/mongodb/mongodb COMPOSER_ARGS=update --no-interaction --prefer-source PHPUNIT_ARGS=--process-isolation help: @echo -e "\t$$ make vm" @echo -e "\t - Launches VMs for running multiple MongoDB variations" @echo -e "\t$$ make list-servers" @echo -e "\t - Lists running servers, and their URIs" @echo -e "\t$$ make test-bootstrap" @echo -e "\t - Starts up MongoDB through mongo-orchestration" @echo "" @echo -e "\t$$ make coveralls" @echo -e "\t - Creates code coverage report using coveralls" @echo -e "\t$$ make coverage" @echo -e "\t - Creates code coverage report using gcov" @echo "" @echo -e "\t$$ make composer" @echo -e "\t - Installs test dependencies using composer" @echo "" @echo -e "\t$$ make distcheck" @echo -e "\t - Builds the archive, runs the virtual tests" @echo "" @echo -e "\t$$ make release" @echo -e "\t - Packages the archive, runs the tests locally and virtual" @echo "" @echo -e "\t$$ make package" @echo -e "\t - Creates the pecl archive to use for provisioning" @echo -e "\t$$ make test-virtual" @echo -e "\t - Provisions some VMs, installs the pecl archive and executes the tests" mv-coverage: @if test -e $(top_srcdir)/coverage; then \ echo "Moving previous coverage run to coverage-$(DATE)"; \ mv coverage coverage-$(DATE); \ fi lcov-coveralls: lcov --gcov-tool $(top_srcdir)/.llvm-cov.sh --capture --directory . --output-file .coverage.lcov --no-external lcov-local: lcov --gcov-tool $(top_srcdir)/.llvm-cov.sh --capture --derive-func-data --directory . --output-file .coverage.lcov --no-external coverage: mv-coverage lcov-local genhtml .coverage.lcov --legend --title "mongodb code coverage" --output-directory coverage coveralls: mv-coverage lcov-coveralls coveralls --exclude src/libbson --exclude src/libmongoc --exclude src/contrib --exclude lib --exclude tests composer: @command -v composer >/dev/null 2>&1; \ if test $$? -eq 0; then \ composer $(COMPOSER_ARGS) ;\ if test -d $(LIB_PATH); then \ composer $(COMPOSER_ARGS) --working-dir $(LIB_PATH) ;\ fi \ elif test -r composer.phar; then \ php composer.phar $(COMPOSER_ARGS); \ if test -d $(LIB_PATH); then \ php $(top_srcdir)/composer.phar $(COMPOSER_ARGS) --working-dir $(LIB_PATH) ;\ fi \ else \ echo "Cannot find composer :("; \ echo "Aborting."; \ exit 1; \ fi vm: @command -v vagrant >/dev/null 2>&1 || { echo >&2 "Vagrant needs to be installed to run vms"; exit 1; } @vagrant up ldap mo list-servers: php scripts/list-servers.php test-bootstrap: php scripts/start-servers.php distcheck: package test-virtual test-virtual: package sh ./scripts/run-tests-on.sh freebsd sh ./scripts/run-tests-on.sh precise32 sh ./scripts/run-tests-on.sh precise64 testunit: composer @command -v phpunit >/dev/null 2>&1; \ if test $$? -eq 0; then \ pushd $(LIB_PATH) ;\ phpunit $(PHPUNIT_ARGS) ;\ popd ;\ elif test -r phpunit.phar; then \ pushd $(LIB_PATH) ;\ php $(top_srcdir)/phpunit.phar $(PHPUNIT_ARGS) ;\ popd ;\ else \ echo "Cannot find phpunit :("; \ echo "Aborting."; \ exit 1; \ fi testall: composer test testunit testclean: @for group in generic standalone; do \ find $(top_srcdir)/tests/$$group -type f -name "*.diff" -o -name "*.exp" -o -name "*.log" -o -name "*.mem" -o -name "*.out" -o -name "*.php" -o -name "*.sh" | xargs rm -f; \ done; mongodbdep: release: test distcheck @echo "Please run:" @echo " " git add RELEASE-$(MONGODB_VERSION) @echo " " git commit -m \"Add $(MONGODB_VERSION) release notes\" @echo " " git tag -a -m \"Release $(MONGODB_VERSION)\" $(MONGODB_VERSION) @echo " " git push --tags @echo " " make release-docs @echo "And don't forget to bump version in php_phongo.h" package: ChangeLog package.xml @git checkout RELEASE-$(MONGODB_MINOR) pecl package package.xml @cat RELEASE-$(MONGODB_MINOR) >> RELEASE-$(MONGODB_VERSION) @mv RELEASE-$(MONGODB_VERSION) RELEASE-$(MONGODB_MINOR) docs: mkdocs build --clean release-docs: docs mkdocs gh-deploy --clean package.xml: RELEASE php bin/prep-release.php $(MONGODB_VERSION) $(MONGODB_STABILITY) RELEASE: @echo "RELEASE $(MONGODB_VERSION)" >> RELEASE-$(MONGODB_VERSION) @echo "-------------" >> RELEASE-$(MONGODB_VERSION) @git log --pretty=format:"%ad %an <%ae>%n%x09* %s%n" --no-merges --date short --since="$$(git show -s --format=%ad `git rev-list --tags --max-count=1`)" >> RELEASE-$(MONGODB_VERSION) @echo -e "\n" >> RELEASE-$(MONGODB_VERSION) ChangeLog: @git log --pretty=format:"%ad %an <%ae>%n%x09* %s%n" --date short > ChangeLog mongodb-1.1.5/README.md0000664000175000017500000000457612673034026014301 0ustar jmikolajmikola# pecl/mongodb (MongoDB driver for PHP) [![Build Status](https://api.travis-ci.org/mongodb/mongo-php-driver.png?branch=master)](https://travis-ci.org/mongodb/mongo-php-driver) [![Coverage Status](https://coveralls.io/repos/mongodb/mongo-php-driver/badge.svg?branch=master&service=github)](https://coveralls.io/github/mongodb/mongo-php-driver?branch=master) This is the low-level PHP driver for MongoDB. The API is the same as the HHVM driver for MongoDB. The documentation for both of them is the same, and can be found at http://docs.php.net/manual/en/set.mongodb.php The driver is written to be a bare bone layer to talk to MongoDB, and therefore misses many convenience features. Instead, these convenience methods have been split out into a layer written in PHP, the [MongoDB Library](http://mongodb.github.io/mongo-php-library/). Using this library should be your preferred way of interacting with MongoDB. Please note that the new HHVM and PHP drivers implement a **different API** from the legacy driver at http://pecl.php.net/package/mongo; therefore existing libraries that use the legacy driver (e.g. [Doctrine MongoDB's ODM](http://doctrine-mongodb-odm.readthedocs.org/en/latest/)) will not work with the new drivers. In the long run, we hope that userland packages will be built atop this driver to implement various APIs (e.g. a BC layer for the existing driver, new fluent interfaces), management utilities (for creating admin utilities and cluster management applications), and other interesting libraries. ## Documentation - http://docs.php.net/set.mongodb - http://mongodb.github.io/mongo-php-driver ## Installation To build and install the driver: ``` $ pecl install mongodb $ echo "extension=mongodb.so" >> `php --ini | grep "Loaded Configuration" | sed -e "s|.*:\s*||"` ``` We recommend using this extension in conjunction with our [userland library](https://github.com/mongodb/mongo-php-library), which is distributed as [mongodb/mongodb](https://packagist.org/packages/mongodb/mongodb) for Composer. ## Contributing See [CONTRIBUTING.md](CONTRIBUTING.md) ## Related Projects - [HHVM Implementation of this driver](https://github.com/mongodb/mongo-hhvm-driver) - [Official high-level library](https://github.com/mongodb/mongo-php-library) - [MongoDB Transistor](https://github.com/bjori/mongo-php-transistor) Lightweight ODM using the [Persistable](http://php.net/bson\\persistable) interface mongodb-1.1.5/RELEASE-00000664000175000017500000024075312673034026014161 0ustar jmikolajmikolaRELEASE 0.6.3 -------------- 2015-05-06 Hannes Magnusson * prep for 0.6.3 2015-05-06 Hannes Magnusson * PHPC-294: Fix path to build directory 2015-05-06 Jeremy Mikola * back to -dev 2015-05-06 Jeremy Mikola * Add 0.6.2 release notes RELEASE 0.6.2 -------------- 2015-05-06 Jeremy Mikola * Bump stability 2015-05-06 Jeremy Mikola * back to -dev 2015-05-06 Jeremy Mikola * Add 0.6.1 release notes RELEASE 0.6.1 -------------- 2015-05-06 Jeremy Mikola * Bump stability 2015-05-05 Hannes Magnusson * Fix build outside of srcdir 2015-05-04 Hannes Magnusson * back to -dev 2015-05-04 Hannes Magnusson * Add 0.6.0 release notes RELEASE 0.6.0 -------------- 2015-05-04 Hannes Magnusson * Bump stability 2015-05-04 Hannes Magnusson * Exceptions live in their own folder now 2015-05-04 Hannes Magnusson * Add coveralls badger 2015-05-04 Hannes Magnusson * Use the coveralls token for 10gen-labs/mongo-php-driver-prototype not my personal one 2015-05-04 Jeremy Mikola * Merge pull request #45 from jmikola/multiple-toArray 2015-05-04 Jeremy Mikola * PHPC-282: Test for multiple Cursor::toArray() calls 2015-05-04 Jeremy Mikola * Merge pull request #44 from jmikola/phpc-255 2015-05-04 Jeremy Mikola * PHPC-255: Cursors cannot rewind after starting iteration 2015-05-04 Jeremy Mikola * PHPC-282: Remove tests for multiple iterators on the same Cursor 2015-05-04 Jeremy Mikola * PHPC-282: Cursor should not yield multiple iterators 2015-05-04 Jeremy Mikola * PHPC-284: Create MongoDB\Driver\Exception\LogicException class 2015-05-04 Jeremy Mikola * Merge pull request #43 from jmikola/phpc-283 2015-05-04 Jeremy Mikola * Use common return for zval_to_bson() bsonSerialize() error path 2015-05-04 Jeremy Mikola * PHPC-283: UnexpectedValueException for invalid bsonSerialize() return value 2015-05-04 Jeremy Mikola * Merge pull request #42 from jmikola/phpc-179 2015-05-01 Jeremy Mikola * PHPC-280: WriteConcern should always set journal/fsync boolean args 2015-05-01 Jeremy Mikola * Document WriteConcern $w param as integer|string 2015-05-01 Jeremy Mikola * PHPC-179: Show unset journal/fsync as null in WriteConcern debug handler 2015-05-04 Jeremy Mikola * Merge pull request #40 from jmikola/phpc-274 2015-04-26 Jeremy Mikola * PHPC-274: Regression test for root BSON\Serializable encoding 2015-04-26 Jeremy Mikola * PHPC-275: object_to_bson() handling for invalid bsonSerialize() retval 2015-04-24 Jeremy Mikola * PHPC-274: Fix zval_to_bson() encoding of BSON\Serializable objects 2015-05-04 Jeremy Mikola * Merge pull request #41 from jmikola/phpc-278 2015-04-30 Jeremy Mikola * PHPC-278: nModified may be null for legacy writes 2015-04-27 Hannes Magnusson * PHPC-269: Travis mojo again 2015-04-24 Hannes Magnusson * PHPC-272: Move exceptions into MongoDB\Driver\Exception namespace 2015-04-24 Hannes Magnusson * Post-release-bump-version 2015-04-24 Hannes Magnusson * Add 0.5.1 release notes RELEASE 0.5.1 -------------- 2015-04-24 Hannes Magnusson * Bump version to 0.5.1-alpha 2015-04-24 Hannes Magnusson * Include the pre-generated fixtures in the package 2015-04-24 Hannes Magnusson * PHPC-241: Don't try to use local timezone 2015-04-24 Hannes Magnusson * Fix extension name -- and recommend the developers flags 2015-04-24 Hannes Magnusson * PHPC-241: mongodb.debug improvements 2015-04-24 Hannes Magnusson * Fix unused result warning - and use the localtime in logs 2015-04-23 Hannes Magnusson * Update testing section and add related section 2015-04-23 Hannes Magnusson * Fix coveralls build 2015-04-23 Hannes Magnusson * PHPC-270: Several test fail because of missing enableTestCommands 2015-04-23 Hannes Magnusson * PHPC-270: add TESTCOMMANDS() skipif to confirm mongod is running with required options 2015-04-23 Hannes Magnusson * PHPC-269: Fix travis setup 2015-04-23 Hannes Magnusson * PHPC-268: Update tests to declare which environments they need 2015-04-23 Hannes Magnusson * PHPC-268: Add NEEDS() function to check if that environment is available 2015-04-23 Hannes Magnusson * Object IDs change, fix test 2015-04-23 Hannes Magnusson * PHPC-247: Remove 'faker' as prerequisite from running our full test suite 2015-04-23 Hannes Magnusson * PHPC-247: Remove on-the-fly composer generated fixtures 2015-04-23 Hannes Magnusson * PHPC-247: Use the bundled pregenerated fixtures 2015-04-23 Hannes Magnusson * PHPC-89: Bundle generated fixtures and make them easily loadable 2015-04-23 Hannes Magnusson * PHPC-260: Allow/use "object" in setTypeMap() as alias/preferred for "stdclass" 2015-04-23 Hannes Magnusson * PHPC-267; _id generated on embedded document 2015-04-23 Hannes Magnusson * PHPC-265: BSON encoding unsupoprted types (Resource) should fail 2015-04-23 Hannes Magnusson * PHPC-266: Add MongoDB\Driver\UnexpectedValueException 2015-04-22 Hannes Magnusson * Bump copyright -- happy 2015 2015-04-22 Hannes Magnusson * PHPC-75: Improve code coverage 2015-04-22 Hannes Magnusson * No need for code-coverage for contrib 2015-04-23 Hannes Magnusson * Merge pull request #39 from remicollet/issue-phpc258 2015-04-23 Remi Collet * PHPC-258: make all filed needed for test as role="test" 2015-04-22 Hannes Magnusson * Merge branch 'remicollet-issue-libbson' 2015-04-22 Remi Collet * PHPC-259: add --with-libbson option 2015-04-21 Jeremy Mikola * Mongo Orchestration now works with PyMongo 3.0 2015-04-21 Hannes Magnusson * Back to -dev 2015-04-21 Hannes Magnusson * Add 0.5.0 release notes 2015-04-21 Hannes Magnusson * Bump stability RELEASE 0.5.0 -------------- 2015-04-21 Hannes Magnusson * Bump stability 2015-04-21 Hannes Magnusson * Add 0.5.0 release notes 2015-04-21 Hannes Magnusson * Fix tests on 5.3 -- and use consistent db/collection 2015-04-21 Hannes Magnusson * Fix test - set my favorite ini option: date.timezone 2015-04-21 Hannes Magnusson * Fix tests 2015-04-21 Hannes Magnusson * PHPC-241: Include lib versions and uri in the logs 2015-04-21 Hannes Magnusson * Use the pretty MONGOC macros 2015-04-21 Hannes Magnusson * Remove dead code 2015-04-21 Hannes Magnusson * Move the init function to where all the others are and add folding markers 2015-04-21 Jeremy Mikola * Merge pull request #37 2015-04-17 Jeremy Mikola * Current element is already freed in php_phongo_cursor_free() 2015-04-16 Jeremy Mikola * Test Cursor iteration handlers and ensure rewind doesn't reset position 2015-04-16 Jeremy Mikola * Tests for multiple iterators sharing the same Cursor 2015-04-15 Jeremy Mikola * PHPC-240: Rely on libmongoc for command cursor iteration 2015-04-14 Jeremy Mikola * PHPC-240: Regression tests for command cursor getmore 2015-04-21 Hannes Magnusson * PHPC-254: Remove unused RINIT and RSHUTDOWN handlers 2015-04-21 Hannes Magnusson * PHPC-253: bump mongoc after CDRIVER-611 fix 2015-04-16 Hannes Magnusson * PHPC-249: empty array should be serialized as array 2015-04-16 Hannes Magnusson * PHPC-248: Allow ->setTypeMap() to set 'array' and 'stdclass' 2015-04-15 Hannes Magnusson * PHPC-245: Allow embedding objects in updates 2015-04-15 Hannes Magnusson * PHPC-245: executeUpdate() converts objects to arrays 2015-04-14 Hannes Magnusson * PHPC-244: Cannot use object of type Person as array 2015-04-14 Hannes Magnusson * PHPC-243: Manager->executeUpdate() option is supposed to be 'multi' 2015-04-14 Hannes Magnusson * Merge pull request #35 from bjori/PHPc-239 2015-04-14 Hannes Magnusson * PHPC-239: Cursor refcount issues 2015-04-14 Hannes Magnusson * Merge pull request #36 from derickr/align-and-missing-break-comment 2015-04-14 Derick Rethans * Align code and added the "break intentionally ommitted" comment 2015-04-13 Hannes Magnusson * PHPC-237: Update PHP version requirement in package.xml 2015-04-10 Hannes Magnusson * post-release pump 2015-04-10 Hannes Magnusson * Add 0.4.1 release notes RELEASE 0.4.1 -------------- 2015-04-10 Jeremy Mikola * Prep 0.4.1 release 2015-04-10 Hannes Magnusson * PHPC-236: 5.3-zts build broken 2015-04-10 Hannes Magnusson * Back to -dev 2015-04-10 Hannes Magnusson * prep 0.4.0 release RELEASE 0.4.0 -------------- 2015-04-10 Hannes Magnusson * Install ext/zlib so we can pecl install .tgz 2015-04-10 Hannes Magnusson * mo will automatically upgrade pymongo -- we need to downgrade 2015-04-10 Hannes Magnusson * mongo-orchestration isn't happy about the recent pymongo3.0 release 2015-04-10 Jeremy Mikola * Update description for Cursor::getServer() 2015-04-09 Hannes Magnusson * PHPC-234: Run test suite automatically on FreeBSD 10.1 2015-04-09 Hannes Magnusson * PHPC-235: Fix out-of-src builds on FreeBSD 2015-04-09 Hannes Magnusson * Initial script to provision on FreeBSD 2015-04-09 Hannes Magnusson * Initial script to provision on Windows 2015-04-09 Hannes Magnusson * Fix windows build 2015-04-09 Hannes Magnusson * Simplify hash and fix windows build 2015-04-09 Hannes Magnusson * Rename the compat header - its much more then PHP5.3 issues now 2015-04-09 Hannes Magnusson * Fix build on windows -- no strtoll() 2015-04-09 Hannes Magnusson * Fix warning, return in noreturn function 2015-04-09 Hannes Magnusson * Fix zts build 2015-04-09 Hannes Magnusson * Fix php_flock() warning on windows 2015-04-09 Hannes Magnusson * PHPC-213: Disable extra bson type alignment 2015-04-09 Hannes Magnusson * Bumpidy bump 2015-04-09 Hannes Magnusson * PHPC-233: Mark the ctor as private for internally created value objects 2015-04-08 Hannes Magnusson * PHPC-80: Create distcheck target 2015-04-08 Hannes Magnusson * Convert int64 that overflow 32bit long to strings 2015-04-08 Hannes Magnusson * Convert overflown int64 to strings and print a warning 2015-04-08 Hannes Magnusson * Fix path to tests when executed through pecl run-tests 2015-04-08 Hannes Magnusson * Ignore untracked files in these repos 2015-04-08 Hannes Magnusson * libbson & mongoc seem to have fixed a lot of warnings -- enable all of ours 2015-04-08 Hannes Magnusson * Workaround CDRIVER-610 2015-04-08 Hannes Magnusson * Apparently there is a function for this! 2015-04-08 Hannes Magnusson * Fix zts build.. TSRMLS_FETCH_FROM_CTX declares variables and therefore must come first 2015-04-07 Hannes Magnusson * Remove noop log handler 2015-04-07 Hannes Magnusson * PHPC-231: Manager instances should not free streams that are still in use 2015-04-07 Hannes Magnusson * bump dependencies for PHPC-231 & PHPC-213 2015-04-07 Jeremy Mikola * PHPC-232: Fix capitalization for WriteResult::getWriteConcern() 2015-04-07 Jeremy Mikola * PHPC-231: Regression test for Manager destruct stream freeing 2015-04-06 Jeremy Mikola * Merge pull request #33 2015-04-06 Jeremy Mikola * Remove unnecessary php_phongo_cursor_free_current() call 2015-04-06 Jeremy Mikola * Re-use cursor_free_current() in cursor_free() 2015-04-06 Jeremy Mikola * PHPC-215: Fix Cursor iteration through IteratorIterator 2015-04-03 Jeremy Mikola * PHPC-225: Test Cursor::isDead() and kill on destruct 2015-04-03 Jeremy Mikola * PHPC-224: Consolidate Result and Cursor classes into one 2015-04-03 Jeremy Mikola * PHPC-224: Remove Cursor class, which implements Iterator 2015-04-03 Hannes Magnusson * PHPC-207: Correct serialized data examples for ODS documentation 2015-04-03 Hannes Magnusson * PHPC-210 & PHPC-209 & PHPC-207 Fix BSON ODM/ODS 2015-04-03 Hannes Magnusson * PHPC-208: Restrict ODS to "__pclass" fieldnames 2015-04-03 Hannes Magnusson * PHPC-194: Implement Manager::selectServer() method to wrap SDAM server selection 2015-04-03 Hannes Magnusson * In PHP5.3 we hit the __wakeUp() which has slightly different exception 2015-04-03 Hannes Magnusson * Merge pull request #34 from serebro/patch-1 2015-04-03 Sergey * Docs small fix 2015-04-03 Hannes Magnusson * PHPC-190: Provide __wakeUp() to disable unserialize() 2015-04-03 Hannes Magnusson * This apt-get update is slow -- no need to execute it all the time 2015-04-03 Hannes Magnusson * PHPC-191 && PHPC-192: Add verify_expiry && verify_peer_name certificate verify options 2015-04-02 Hannes Magnusson * PHPC-223: Use explicit SSL options rather then stream context 2015-04-02 Hannes Magnusson * Fix setting debug logging as part of the driverOptions 2015-04-02 Hannes Magnusson * Private Public doesn't exists... This is supposed to be private :D 2015-04-02 Hannes Magnusson * Cleanup after test 2015-04-02 Hannes Magnusson * Make it possible to cleanup other db and collections used 2015-04-01 Hannes Magnusson * Fix tests when executed outside of srcroot 2015-04-01 Hannes Magnusson * PHPC-222: WriteConcernError can cause segfaults on Ubuntu Precise 32bit 2015-04-01 Hannes Magnusson * PHPC-220: BSON\UTCDatetime broken on 32bit 2015-04-01 Hannes Magnusson * Fix compile warning on 32bit 2015-04-01 Hannes Magnusson * Fix incompatible pointer type in PHP 5.3 2015-04-01 Hannes Magnusson * Include usable gdbinit 2015-04-01 Hannes Magnusson * PHPC-221: Add Ubuntu Precise (12.04.5) 32bit image 2015-04-01 Hannes Magnusson * PHPC-219 - BSON\Javascript segfaults on Ubuntu Precise 32bit 2015-04-01 Hannes Magnusson * PHPC-221: Rename the identifier to precise64 as we'll be adding 32bit soon 2015-03-31 Jeremy Mikola * Merge pull request #32 2015-03-31 Jeremy Mikola * PHPC-204: Result::toArray() should respect type map configuration 2015-03-31 Jeremy Mikola * PHPC-203: Result::toArray() should proxy iterator_to_array($this) 2015-03-31 Hannes Magnusson * Make sure we install the latest package in case of multiple rebuilds of same name 2015-03-31 Jeremy Mikola * Merge pull request #31 2015-03-30 Jeremy Mikola * PHPC-214: Result does not need custom iterator classes 2015-03-30 Hannes Magnusson * Forcefully install the new archive, even though it exists 2015-03-30 Hannes Magnusson * PHPC-216: PHP5.5 change the prototype of get_current_key leading to 2015-03-30 Hannes Magnusson * PHPC-216: Include our pem files in the pecl archive 2015-03-30 Hannes Magnusson * PHPC-216: Use array(), not [], for PHP5.3 compatibility 2015-03-30 Hannes Magnusson * Split release target into release and packaging 2015-03-30 Hannes Magnusson * PHPC-218: Provision ubuntu image and install & run the test suite 2015-03-30 Hannes Magnusson * No need to sudo, run the scripts as priveleged 2015-03-30 Hannes Magnusson * PHPC-216: PHP5.3 test suite fixes 2015-03-30 Hannes Magnusson * PHPC-217: Include the connection tests in pecl package 2015-03-30 Hannes Magnusson * PHPC-213: Memory alignment issues on FreeBSD 2015-03-30 Hannes Magnusson * Fix stability name according to pecl rules 2015-03-30 Hannes Magnusson * PHPC-216: PHP5.3 test suite fixes 2015-03-27 Hannes Magnusson * Re align 2015-03-27 Hannes Magnusson * PHPC-212: undefined symbol: _mongoc_sasl_set_service_host - patch by remi@php.net 2015-03-26 Hannes Magnusson * Ignore coverage files 2015-03-25 Hannes Magnusson * bump version 2015-03-25 Hannes Magnusson * Merge pull request #28 from jmikola/phpc-201 2015-03-25 Hannes Magnusson * Add 0.3.1 release notes RELEASE 0.3.1 -------------- 2015-03-25 Hannes Magnusson * bump version for windows packaging fix 2015-03-25 Hannes Magnusson * PHPC-211: Windows libbson and mongoc config files missing in release archive 2015-03-25 Hannes Magnusson * Link to the docs on php.net 2015-03-25 Hannes Magnusson * Use pecl for installing 2015-03-25 Hannes Magnusson * Bump version 2015-03-25 Hannes Magnusson * Add 0.3.0 release notes RELEASE 0.3.0 -------------- 2015-03-25 Hannes Magnusson * Add config.w32 to package.xml 2015-03-25 Hannes Magnusson * Use absolute paths in skipifs too 2015-03-25 Hannes Magnusson * Update bundles for windows fixes 2015-03-25 Hannes Magnusson * PHPC-175: Fix header includes on Windows 2015-03-25 Hannes Magnusson * PHPC-175: Fix build on 32bit 2015-03-25 Hannes Magnusson * PHPC-175: Windows doesn't have these compiler attributes 2015-03-25 Hannes Magnusson * Fix windows bson config 2015-03-25 Hannes Magnusson * IPHPC-176: Copy build templates, add missing file & set build flags 2015-03-25 Hannes Magnusson * Use absolute paths on in tests so they can run easier on windows 2015-03-25 Hannes Magnusson * Absolute path is required to run tests on windows 2015-03-25 Hannes Magnusson * Allow mongoc_init() to not use our mm 2015-03-25 Hannes Magnusson * bump mongoc with windows fixes 2015-03-25 Hannes Magnusson * PHPC-200: Don't set stream initiator when creating client fails 2015-03-25 Hannes Magnusson * PHPC-199: Missing file from mongoc in config.m4 2015-03-24 Hannes Magnusson * Initial win32 attempt 2015-03-24 Hannes Magnusson * Bundle windows configs 2015-03-24 Hannes Magnusson * Improve code coverage 2015-03-23 Hannes Magnusson * Simplify 2015-03-23 Hannes Magnusson * Providing higher init size is worse then providing none 2015-03-23 Hannes Magnusson * Add raises() helper, similar to throws() except for php warnings/notices/deprecated/... 2015-03-24 Hannes Magnusson * ignore mongodb*tgz release files and "failed.txt" from run-tests 2015-03-24 Hannes Magnusson * Bump libbson with timeval fix and mongoc with various sdam fixes 2015-03-23 Jeremy Mikola * Update PECL install instructions for alpha release 2015-03-23 Hannes Magnusson * Include the license file for next release 2015-03-23 Hannes Magnusson * Update naming after PHPC-174 2015-03-23 Hannes Magnusson * Bump version 2015-03-23 Hannes Magnusson * Add 0.2.0 release notes RELEASE 0.2.0 -------------- 2015-03-23 Hannes Magnusson * PHPC-174: Rename module registration, constants and so on to mongodb 2015-03-23 Hannes Magnusson * Bump release to 0.2.0-alpha 2015-03-23 Hannes Magnusson * Include the version and config templates 2015-03-23 Hannes Magnusson * Only run our tests as part of release for now 2015-03-23 Hannes Magnusson * PHPC-174: Rename phongo to mongodb 2015-03-23 Hannes Magnusson * PHPC-174: Use consistent extension names for PHP and HHVM drivers 2015-03-23 Hannes Magnusson * PHPC-195: Fix typo and couple of missing incldues 2015-03-23 Hannes Magnusson * PHPC-195: Remove mongoc/bson header file workarounds 2015-03-23 Hannes Magnusson * Test for PHPC-186 2015-03-23 Hannes Magnusson * Remove char * casting, the macro soup leads to incorrect sizeof 2015-03-20 Hannes Magnusson * Fix zts 2015-03-20 Hannes Magnusson * PHPC-183: Add -Wdeclaration-after-statement to --enable-developers-flags 2015-03-20 Hannes Magnusson * PHPC-183: Fix compiler warnings with -Wdeclaration-after-statement 2015-03-20 Hannes Magnusson * PHPC-189: Implement Manager->getServers() 2015-03-20 Hannes Magnusson * PHPC-188: Populate MongoDB\Driver\Server 2015-03-20 Hannes Magnusson * PHPC-24 PHPC-77 PHPC-69 Provide a functioning Server object 2015-03-19 Hannes Magnusson * bump submodule to mongoc 1.2.0-dev - includes sdam stuff 2015-03-18 Hannes Magnusson * PHPC-106: Comment out var_dump() data for now 2015-03-18 Hannes Magnusson * PHPC-106: Enable mongoc SDAM build 2015-03-18 Hannes Magnusson * PHPC-106: Connect asynchronouslyish 2015-03-19 Hannes Magnusson * PHPC-106: Implement the new poll callback 2015-03-18 Hannes Magnusson * In SDAM this is forbidden and throws exception 2015-03-18 Hannes Magnusson * Show the response when the test fails 2015-03-18 Hannes Magnusson * Store the original mongoc_uri_t not just the options bson 2015-03-18 Hannes Magnusson * Add a little tracing love 2015-03-18 Hannes Magnusson * Properly block on socket writes 2015-03-18 Hannes Magnusson * Fix null pointer exception 2015-03-17 Hannes Magnusson * Unhide this 2015-03-17 Jeremy Mikola * Merge pull request #27 2015-03-17 Jeremy Mikola * Return const struct pointers from zval getters 2015-03-17 Jeremy Mikola * PHPC-181: Discard const qualifiers for PHP API 2015-03-17 Jeremy Mikola * PHPC-181: Use const for pointer args where applicable 2015-03-16 Hannes Magnusson * PHPC-180: Fix limited batch import 2015-03-16 Hannes Magnusson * PHPC-180: No need to sleep anything, we get a fresh connection in next test 2015-03-16 Hannes Magnusson * PHPC-180: We now load 1024 users 2015-03-16 Hannes Magnusson * PHPC-180: We now generate 1024 users, only load the first 100 2015-03-16 Hannes Magnusson * PHPC-180: Cache the fixtures 2015-03-16 Hannes Magnusson * Surpress timezone warning by adding it to the ini 2015-03-16 Hannes Magnusson * PHPC-180: Rename constant and pass the cleanup uri explicitly 2015-03-16 Hannes Magnusson * PHPC-180: Replace this Orchestration wrapper with significantly simpler code 2015-03-16 Hannes Magnusson * Use underscore for the id so we can declare them as constants in php 2015-03-16 Hannes Magnusson * Use readable name for the replicaset nodes 2015-03-16 Hannes Magnusson * Minor README updates 2015-03-13 Jeremy Mikola * Merge pull request #26 2015-03-12 Jeremy Mikola * PHPC-168: Implement WriteResult::isAcknowledged() 2015-03-12 Jeremy Mikola * PHPC-170: Don't set write concern on bulk unnecessarily 2015-03-12 Jeremy Mikola * PHPC-177: Include all fields in WriteConcern debug output 2015-03-12 Jeremy Mikola * Remove unnecessary Manager and apply EXPECTF patterns 2015-03-12 Jeremy Mikola * Update Ubuntu's package repository before installing 2015-03-12 Hannes Magnusson * Fixed missing type specifier warning 2015-03-12 Hannes Magnusson * Fix build on MacOSX 2015-03-11 Hannes Magnusson * Its a bulk 2015-03-11 Hannes Magnusson * post release bump 2015-03-11 Hannes Magnusson * Add 0.1.5 release notes RELEASE 0.1.5 -------------- 2015-03-11 Hannes Magnusson * MO now actually creates this initial user, use correct subject to fix the X509 tests 2015-03-11 Hannes Magnusson * libbson 1.1.2 & mongoc 1.1.2 2015-03-11 Hannes Magnusson * Add "make help" since I always forget the names 2015-03-05 Hannes Magnusson * PHP5.6 change serveral TLS verfication defaults 2015-03-05 Hannes Magnusson * PHPC-171: SSL Doesn't work in PHP5.6 2015-03-04 Hannes Magnusson * Bump submodules 2015-03-04 Hannes Magnusson * Bump bundled version 2015-03-04 Hannes Magnusson * Fix tests for MongoDB 3.0.0 2015-03-04 Hannes Magnusson * PHPC-129: Fix tests for HIPPO can't throw InvalidArgumentException on argument errors 2015-03-03 Hannes Magnusson * Bump mongoc for PHPC-167 2015-03-03 Hannes Magnusson * Add micro-optimization tip for the future 2015-03-03 Hannes Magnusson * PHPC-129: HIPPO can't throw InvalidArgumentException on argument errors 2015-03-03 Hannes Magnusson * Simplify debug logging logic when running tests standalone 2015-03-03 Hannes Magnusson * PHPC-163: Throw BulkWriteException on BulkWrite failure 2015-02-27 Hannes Magnusson * PHPC-166: Disable (un)serializing of phongo objects 2015-02-20 Hannes Magnusson * PHPC-165: Rename WriteBatch to BulkWrite 2015-02-19 Hannes Magnusson * PHPC-164: Throw MongoDB\Driver\ConnectionTimeoutException 2015-02-19 Hannes Magnusson * This is a Manager, not MongoClient 2015-02-19 Hannes Magnusson * Ignore me. Trim trailing space 2015-02-19 Hannes Magnusson * PHPC-107: Throw ExecutionTimeoutException for maxTimeMs 2015-02-18 Hannes Magnusson * PHPC-159: memleak on failed path resolving 2015-02-18 Hannes Magnusson * PHPC-158: Split queryFlags bitmask option into specific options 2015-02-18 Hannes Magnusson * PHPC-157: Consolidate CommandResult and QueryResult classes 2015-02-18 Hannes Magnusson * PHPC-157: QueryResult and CommandResult are now Result 2015-02-18 Hannes Magnusson * rebase with Result.c 2015-02-18 Hannes Magnusson * PHPC-157: Renamed getResponseDocument() to toArray() 2015-02-18 Hannes Magnusson * PHPC-157: Consolidate CommandResult and QueryResult classes 2015-02-18 Hannes Magnusson * PHPC-157: Remove QueryResult 2015-02-18 Hannes Magnusson * bump mongoc 2015-02-18 Hannes Magnusson * PHPC-155: WriteConcernError->getInfo() can be scalar 2015-02-18 Hannes Magnusson * Add a note about PHPC-72 2015-02-18 Hannes Magnusson * PHPC-154: WriteError can have info field 2015-02-06 Hannes Magnusson * PHPC-153: Rename cursorFlags to queryFlags in Query 2015-02-06 Hannes Magnusson * PHPC-152: Throw MongoDB\Driver\InvalidArgumentException on argument errors 2015-02-06 Hannes Magnusson * Throw our RuntimeException, not SPL 2015-02-02 Hannes Magnusson * post release bump 2015-02-02 Hannes Magnusson * Add 0.1.4 release notes RELEASE 0.1.4 -------------- 2015-02-02 Hannes Magnusson * prep for 0.1.4 release 2015-02-02 Hannes Magnusson * PHPC-151: Bump to libbson-1.1.0 and mongoc-1.1.0 and fix build 2015-02-02 Hannes Magnusson * This is a result iterator, not cursor 2015-02-02 Hannes Magnusson * PHPC-149: Iterator holding on to dead results 2015-01-30 Hannes Magnusson * NULLify after destroy and clear 2015-01-30 Hannes Magnusson * 0.1.3 is the current release... 2015-01-29 Hannes Magnusson * PHPC-148: var_dump()ing ObjectID should show the ObjectID 2015-01-29 Hannes Magnusson * PHPC-144: MO first-user changes 2015-01-29 Hannes Magnusson * Make sure we have a document before dumping it 2015-01-29 Hannes Magnusson * Add SSL to the persistance hash 2015-01-28 Hannes Magnusson * Quick note about var_dump()ing the cursor, rather then calling iterator_to_array() 2015-01-28 Hannes Magnusson * PHPC-147: Document the ODS 2015-01-28 Hannes Magnusson * PHPC-146: ReadPreferences swapped 2015-01-28 Hannes Magnusson * PHPC-145: Typo in example, operators need to use single quotes 2015-01-28 Hannes Magnusson * PHPC-143: skip auth tests when the server configuration required isn't available 2015-01-27 Hannes Magnusson * Most of our issues with MO seem to be fixed in master 2015-01-27 Hannes Magnusson * PHPC-142: add 'list-servers' target to enumerate all running MO servers 2015-01-27 Hannes Magnusson * PHPC-140: var_dump()ing WriteConcernError and WriteError 2015-01-27 Hannes Magnusson * PHPC-139: var_dump()ing WriteBatch 2015-01-27 Hannes Magnusson * PHPC-138: var_dump()ing WriteConcern 2015-01-27 Hannes Magnusson * PHPC-138: var_dump()ing ReadPreference 2015-01-26 Hannes Magnusson * PHPC-137: var_dump()ing CursorID should show the Cursor ID 2015-01-09 Hannes Magnusson * simplify 2015-01-09 Hannes Magnusson * PHPC-134: Add the internal results here too 2015-01-09 Hannes Magnusson * PHPC-136: var_dump() CommandResult and QueryResult 2015-01-09 Hannes Magnusson * PHPC-133: var_dump()ing cursor 2015-01-09 Hannes Magnusson * PHPC-135: Fix memory leak var_dump()ing Command 2015-01-09 Hannes Magnusson * PHPC-135: Fix memory leak var_dump()ing Query and add test 2015-01-09 Hannes Magnusson * PHPC-134: Add debug info for WriteResult 2015-01-08 Hannes Magnusson * PHPC-110: Fix segfault on standalone nodes :) 2015-01-08 Hannes Magnusson * PHPC-135: Implement debug handler for Query and Command 2015-01-08 Hannes Magnusson * PHPC-110: Fix segfault when var_dump()ing before connecting 2015-01-07 Hannes Magnusson * PHPC-110: Add var_dump() support for MongoDB\Driver\Manager 2015-01-07 Hannes Magnusson * Revert "PHPC-131: Place the rendered files out of this dir" 2015-01-07 Hannes Magnusson * PHPC-131: Place the rendered files out of this dir 2015-01-07 Hannes Magnusson * PHPC-131: Add jira issue collector 2015-01-06 Hannes Magnusson * PHPC-128: MO presets directory needs to be configurable 2015-01-06 Hannes Magnusson * PHPC-128: if there is no cleanup uri then skipit 2015-01-06 Hannes Magnusson * PHPC-128: Maybe orchestration doesn't like IPs? 2015-01-06 Hannes Magnusson * PHPC-128: more travis debugging 2015-01-06 Hannes Magnusson * PHPC-128: ping should be fast 2015-01-06 Hannes Magnusson * PHPC-130: Update the get_current_key handler to support pre-5.5 2015-01-06 Hannes Magnusson * PHPC-128: Debugging why mo on travis doesn't start 2015-01-06 Hannes Magnusson * PHPC-128: use consistent env variable 2015-01-06 Hannes Magnusson * PHPC-128: Start the nodes using MO 2015-01-06 Hannes Magnusson * PHPC-128: -See if this works better for travis 2015-01-06 Hannes Magnusson * PHPC-128: Fix travis setup 2015-01-06 Hannes Magnusson * PHPC-116: Cursor methods should call their respective iterator function handlers 2015-01-06 Hannes Magnusson * Smiplify cursor/results to prep for PHPC-116 2015-01-06 Hannes Magnusson * We don't need to debug this test anymore 2015-01-06 Hannes Magnusson * PHPC-116: Implement invalidate_current handler to reduce code 2015-01-06 Hannes Magnusson * PHPC-128: Startup the mongodb-org freshly installed mongodb 2015-01-05 Hannes Magnusson * PHPC-128: Set the uri to use on travis 2015-01-05 Hannes Magnusson * PHPC-128: Fix running tests on travis 2015-01-05 Hannes Magnusson * We use corporate coverity now 2015-01-05 Hannes Magnusson * PHP-127: Fix test, use the string stderr, not resource STDERR 2015-01-05 Hannes Magnusson * PHPC-42: Implement root level (full document) ODM style serialization 2015-01-05 Hannes Magnusson * PHPC-125: pointer to out of scope variable :] 2015-01-05 Hannes Magnusson * PHPC-123: Wrong sizeof argument 2015-01-05 Hannes Magnusson * PHPC-124: Buffer not null terminated 2015-01-05 Hannes Magnusson * PHPC-126: Fixed unchecked return 2015-01-02 Hannes Magnusson * PHPC-42: BSON Serialization for classes 2014-12-31 Hannes Magnusson * PHPC-121: Use BSON\Serialize::bsonSerialize() during serialization 2014-12-31 Hannes Magnusson * PHPC-96: Add QueryResult->setTypemap() to overwrite array/object mapping 2014-12-31 Hannes Magnusson * WriteConcernError test 2014-12-31 Hannes Magnusson * initialize correctly 2014-12-31 Hannes Magnusson * fix title 2014-12-31 Hannes Magnusson * PHPC-96 & PHPC-119 call the new bsonUnserialize method and optimize things a little 2014-12-31 Hannes Magnusson * PHPC-120: BSON\toArray should support classmap to unserialize as 2014-12-31 Hannes Magnusson * PHPC-119 && PHPC-49: Create PHP interfaces for BSON (un-)serialization 2014-12-31 Hannes Magnusson * Fix array return 2014-12-30 Hannes Magnusson * No need for these anymore 2014-12-30 Hannes Magnusson * PHPC-118: Use MongoDB\Driver namespace for phongo 2014-12-30 Hannes Magnusson * PHPC-96: Retrieve arrays as custom objects 2014-12-29 Hannes Magnusson * PHPC-117: Simplify bson deserialization code 2014-12-23 Hannes Magnusson * PHPC-50: Implement checking socket state handler 2014-12-23 Hannes Magnusson * latest and gratest libmongoc fixes 2014-12-23 Hannes Magnusson * PHPC-115: Remove now-useless GeneratedId 2014-12-23 Hannes Magnusson * If there is no error, pass null to avoid the type hint 2014-12-22 Hannes Magnusson * PHPC-113: WriteConcernError is just one error, not multiple 2014-12-23 Hannes Magnusson * PHPC-114: Implement WriteConcernError->getMessage() 2014-12-23 Hannes Magnusson * Avoid invalid read when logging from replicaset 2014-12-23 Hannes Magnusson * Simplify cli debugging 2014-12-22 Hannes Magnusson * PHPC-112: Sping up ReplicaSet 2014-12-22 Hannes Magnusson * Bump version 2014-12-22 Hannes Magnusson * The development of this driver is now under the PHPC jira project 2014-12-22 Hannes Magnusson * Bump release version in the docs 2014-12-22 Hannes Magnusson * Add 0.1.3 release notes RELEASE 0.1.3 -------------- 2014-12-22 Hannes Magnusson * Fix paths to root dir .phar 2014-12-22 Hannes Magnusson * Add new files to the packager 2014-12-22 Hannes Magnusson * Update composer after the repo renaming 2014-12-22 Hannes Magnusson * mongoc requires newer libbson now 2014-12-22 Hannes Magnusson * bump mongoc 2014-12-22 Hannes Magnusson * rename the Mongo Orchestration name to 'mo' 2014-12-22 Hannes Magnusson * MO PR#161 includes fixes from 155, and adds ssl auth support 2014-12-22 Hannes Magnusson * PHPC-33: Implement X509 support via PHP streams 2014-12-22 Hannes Magnusson * Fix typo in persistent hash 2014-12-19 Jeremy Mikola * Add Apache 2 license 2014-12-19 Hannes Magnusson * PHPC-33: Add tests for X509 2014-12-19 Hannes Magnusson * bump mongoc 2014-12-19 Hannes Magnusson * PHPC-104: Throw MongoDB\AuthenticationException on auth failure 2014-12-19 Hannes Magnusson * Fix test titles 2014-12-18 Hannes Magnusson * bump mongoc 2014-12-18 Hannes Magnusson * Remove useless stuff 2014-12-18 Hannes Magnusson * Workaround https://github.com/10gen/mongo-orchestration/issues/154 2014-12-18 Hannes Magnusson * PHPC-31: Implement PLAIN authentication via PHP streams 2014-12-18 Hannes Magnusson * PHPC-31: Test for PLAIN authentication mechanism 2014-12-18 Hannes Magnusson * PHPC-45: Orchestrate LDAP/PLAIN servers 2014-12-18 Hannes Magnusson * PHPC-45: Orchestarte PLAIN/LDAP authentication mechanism 2014-12-18 Hannes Magnusson * PHPC-103: Virtualize OpenLDAP server using CentOS 2014-12-18 Hannes Magnusson * Reorganize Vagrantfile to make room for more images 2014-12-18 Hannes Magnusson * PHPC-2: Persist connection by the dsn 2014-12-18 Hannes Magnusson * PHPC-101: throw MongoDB\DuplicateKeyException 2014-12-18 Hannes Magnusson * Enable test and fixit 2014-12-17 Hannes Magnusson * PHON-85: Improve test 2014-12-17 Hannes Magnusson * ignore ctags and local vimrc 2014-12-17 Hannes Magnusson * PHON-99: Add & Implement SSLConnectionException 2014-12-17 Hannes Magnusson * PHON-31: Add stream context options 2014-12-17 Hannes Magnusson * PHON-100: Implement connectiontimeoutms 2014-12-17 Hannes Magnusson * PHON-31: Do not overload the stream_initiator with tsrm, we want it for stream context later 2014-12-17 Hannes Magnusson * PHON-98: Implement and properly throw MongoDB\ConnectionException 2014-12-17 Hannes Magnusson * PHON-97: Add MongoDB\RuntimeException 2014-12-17 Hannes Magnusson * PHON-96: Create MongoDB\Exception interface 2014-12-16 Hannes Magnusson * PHON-22: New test to verify standard authentication 2014-12-16 Hannes Magnusson * PHON-23: Add test for connecting to SSL server 2014-12-16 Hannes Magnusson * PHON-6: Split normal SSL and X509 servers 2014-12-16 Hannes Magnusson * PHON-3: Orchestrate standard authentication 2014-12-16 Hannes Magnusson * PHON-6: Orchestrate SSL and X509 2014-12-16 Hannes Magnusson * PHON-7: Trivial Monog Orchestration abstraction 2014-12-16 Hannes Magnusson * exit on failure - and include a greppable error 2014-12-16 Hannes Magnusson * PHON-92: Create standalone MongoDB server 2014-12-16 Hannes Magnusson * PHONG-91: Yes to all questions when installing mongodb 2014-12-16 Hannes Magnusson * PHON-91: Use the vm by default, allow it to be overridden by the environment variable 2014-12-16 Hannes Magnusson * PHON-5: Whopsy, missing file for startting servers hidden by gitignore 2014-12-16 Hannes Magnusson * PHON-91: Use Vagrant to virtualise mongod 2014-12-16 Hannes Magnusson * return true on success 2014-12-15 Hannes Magnusson * Use the MONGODB_URI constant 2014-12-15 Hannes Magnusson * PHON-5: Use Mongo Orchestration to manage MongoDB servers 2014-12-15 Hannes Magnusson * Seperate code from functions 2014-12-16 Hannes Magnusson * remove hyperbole description 2014-12-15 Jeremy Mikola * Merge pull request #24 from hannesvdvreken/master 2014-12-15 Hannes Van De Vreken * Fixed spelling mistake 2014-12-12 Hannes Magnusson * PHP-1337: Implement killing a MongoDB Cursor 2014-12-12 Hannes Magnusson * PHP-1336: Use Cursor->getId(), not Cursor->getCursorId() 2014-12-12 Hannes Magnusson * Call the bson module init 2014-12-12 Hannes Magnusson * PHP-1338: There is actually no DBRef BSON type, its a convention 2014-12-12 Hannes Magnusson * PHP-1181: Improve coverage for BSON\UTCDateTime 2014-12-12 Hannes Magnusson * PHP-1181: Improve coverage for BSON\Timestamp 2014-12-12 Hannes Magnusson * PHP-1181: Improve coverage for BSON\Regex 2014-12-12 Hannes Magnusson * PHP-1181: Improve coverage for BSON\ObjectID 2014-12-12 Hannes Magnusson * Improve exception testing 2014-12-12 Hannes Magnusson * PHP-1181: uhm.. This is minkey test! 2014-12-12 Hannes Magnusson * PHP-1181: Increse BSON\Binary testcoverage 2014-12-12 Jeremy Mikola * Fix composer update and test execution for userland library 2014-12-12 Hannes Magnusson * Proper librt linking on platforms that need it 2014-12-12 Jeremy Mikola * Reformat composer.json and remove redundant autoload block 2014-12-12 Hannes Magnusson * Skip phpunit tests for now, its a bit of an chicken-and-egg issue 2014-12-12 Hannes Magnusson * Update links after moving the repo to 10gen-labs from bjori 2014-12-11 Hannes Magnusson * Fix instructions 2014-12-11 Hannes Magnusson * PHP-1334: Fix build on MacOSX: Don't hardcode librt, we already conditionally check for it 2014-12-10 Jeremy Mikola * Require composer deps before test tasks 2014-12-10 Jeremy Mikola * Use CRUD's PHPUnit config when running tests 2014-12-10 Jeremy Mikola * Use composer update instead of install 2014-12-09 Hannes Magnusson * I have no idea what made me make BSON\Pool 2014-12-09 Hannes Magnusson * Run the phongo-crud tests to 2014-12-09 Hannes Magnusson * PHP-1324: Embed phongo-crud tests under 'testunit' and 'testall' targets 2014-12-09 Hannes Magnusson * Add the phongo-crud to the composer autoloader 2014-12-09 Hannes Magnusson * bump libmongoc without ssl=prefer 2014-12-09 Hannes Magnusson * PHP-1329: Remove ssl=prefer option 2014-12-09 Hannes Magnusson * Fetch phongo-crud to share its tests 2014-12-09 Hannes Magnusson * Search for composer.phar too for those not with it globally installed 2014-12-09 Hannes Magnusson * PHP-1323: Document install instructions from vcs 2014-12-08 Hannes Magnusson * Add documentation build and release targets 2014-12-08 Hannes Magnusson * Bump install instructions 2014-12-08 Hannes Magnusson * Add couple of more reminders 2014-12-08 Hannes Magnusson * Bump version 2014-12-08 Hannes Magnusson * Fix argument passing :] 2014-12-08 Hannes Magnusson * Add release notes RELEASE 0.1.2 -------------- 2014-12-08 Hannes Magnusson * PHP-1322: More renaming 2014-12-08 Hannes Magnusson * PHP-1322 Rename count methods in WriteResults 2014-12-08 Hannes Magnusson * PHP-1320: $batch->update() fails when replacing entire document 2014-12-08 Hannes Magnusson * PHP-1319: Convert this into normalish cursor 2014-12-05 Hannes Magnusson * PHP-1319: Implement command cursors 2014-12-08 Hannes Magnusson * Add tracing to mongoc 2014-12-05 Hannes Magnusson * We are throwing exception here, doesn't matter if we are assigning return value 2014-12-05 Hannes Magnusson * Throw exception on failure 2014-12-05 Hannes Magnusson * Make phongo_throw_exception variadic to improve error messages 2014-12-05 Hannes Magnusson * Fix reference counting of nested bson objects 2014-12-04 Hannes Magnusson * Bump version 2014-12-04 Hannes Magnusson * Commit the release notes 2014-12-03 Hannes Magnusson * Take the release notes from the release file RELEASE 0.1.1 -------------- 2014-12-03 Hannes Magnusson * Take the release notes from the release file 2014-12-03 Hannes Magnusson * Lets not actually tag automatically, just ask politely 2014-12-03 Hannes Magnusson * Whopsy, we need $$ to read the output 2014-12-03 Hannes Magnusson * Update toc and run syntax highlitghting automatically 2014-12-03 Hannes Magnusson * Add command docs 2014-12-03 Hannes Magnusson * WS 2014-12-03 Hannes Magnusson * Initial documentation 2014-12-03 Hannes Magnusson * Move docs to old-docs making way for actual documentation 2014-12-03 Hannes Magnusson * Remove unused command 2014-12-02 Hannes Magnusson * Integer IDs can also be int32 2014-12-02 Hannes Magnusson * Fix 32bit builds 2014-12-02 Hannes Magnusson * PHP-1195: Integers are now represented as int32, as long as they fit 2014-12-02 Hannes Magnusson * Differenciate the connection type by the SSL option 2014-12-02 Hannes Magnusson * Bail out when we cannot connect to the server! 2014-12-02 Hannes Magnusson * PHP-1195: Error out on 32bit platforms if we cannot represent the int 2014-12-02 Hannes Magnusson * PHP-1195: Remove Int32 and Int64 classess 2014-12-02 Hannes Magnusson * Remove misterious BSON\Log class 2014-12-02 Hannes Magnusson * bump libmongoc with ssl fix 2014-12-02 Hannes Magnusson * PHP-1175: Add Support for SSL=true and SSL=prefer 2014-12-02 Hannes Magnusson * PHP-1175: Compile against OpenSSL 2014-12-01 Hannes Magnusson * Improve API consistency between WriteConcern and ReadPreference 2014-11-26 Hannes Magnusson * PHP-1296: Implement WriteConcerns 2014-11-26 Hannes Magnusson * PHP-1295: Memory leak when generating ID for inserts 2014-11-26 Hannes Magnusson * PHP-1294: Emtpy Query Result should still return QueryResult 2014-11-26 Hannes Magnusson * Add an example "document browser" 2014-11-26 Hannes Magnusson * PHP-1293: Writing all debug info is not a good default 2014-11-26 Hannes Magnusson * WS 2014-11-26 Hannes Magnusson * We only allow object/array here, not need for this extra code 2014-11-26 Hannes Magnusson * PHP-1292: BSON Arrays should be... PHP Arrays 2014-11-26 Hannes Magnusson * PHP-1291: memleak when serializing nested objects/array 2014-11-26 Hannes Magnusson * Initialize to NULL 2014-11-26 Hannes Magnusson * Enable the corrupt BSON handler for debugging 2014-11-26 Hannes Magnusson * Add missing arginfo for the BSON encoding functions 2014-11-25 Hannes Magnusson * List commits per release in the RELEASE file 2014-11-25 Hannes Magnusson * Bump version 2014-11-26 Hannes Magnusson * Update README for current situation 2014-11-25 Hannes Magnusson * Ignore the run-tests php.ini 2014-11-25 Hannes Magnusson * We haven't executed the test target yet! RELEASE 0.1.0 -------------- 2014-11-25 Hannes Magnusson * We haven't executed the test target yet! 2014-11-25 Hannes Magnusson * Fix coverage build 2014-11-25 Hannes Magnusson * Create the tag at the end of making the release ball 2014-11-25 Hannes Magnusson * Compiler warnings 2014-11-25 Hannes Magnusson * Running the tests is of course part of a release 2014-11-25 Hannes Magnusson * Ignore generated files 2014-11-25 Hannes Magnusson * Expose version constants and stability 2014-11-25 Hannes Magnusson * Fix version number 2014-11-25 Hannes Magnusson * Get the release number from the module 2014-11-25 Hannes Magnusson * Update travis for build system changes 2014-11-25 Hannes Magnusson * Fix building out of root 2014-11-25 Hannes Magnusson * Generate package.xml and release archive 2014-11-25 Hannes Magnusson * Don't Move this to a dedicated patch target 2014-11-25 Hannes Magnusson * Add CREDITS 2014-11-25 Hannes Magnusson * Add a target to generate a ChangeLog 2014-11-25 Hannes Magnusson * Add a custom build target dependency 2014-11-25 Hannes Magnusson * This seems to be the conventional wisdom setting ulimit on travis 2014-11-25 Hannes Magnusson * PHP-1289: Automatically apply our required patches 2014-11-24 Hannes Magnusson * No longer needed 2014-11-24 Hannes Magnusson * PHP-1289: Revamp the build system to embed libmongoc, libbson and yajl 2014-11-24 Hannes Magnusson * Set ulimit before our trap 2014-11-24 Hannes Magnusson * Don't include libbson or libmongoc in the coverage report 2014-11-24 Hannes Magnusson * Fixed CID-60852: Pointer to local outside scope 2014-11-24 Hannes Magnusson * This is the master branch 2014-11-24 Hannes Magnusson * Fix ZTS - and all the segfaults 2014-11-21 Hannes Magnusson * Attempt to fix stream closing in zts 2014-11-21 Hannes Magnusson * Fix zts builds 2014-11-21 Hannes Magnusson * Use my libmongoc fork for now 2014-11-21 Hannes Magnusson * bump libmongoc in my fork 2014-11-21 Hannes Magnusson * Fixed various memory leaks and compiler warnings 2014-11-21 Hannes Magnusson * PHP-1189: Implement BSON regex type 2014-11-21 Hannes Magnusson * Fixed couple of constify, and renamed a functino to be consistent with'em all 2014-11-11 Jeremy Mikola * PHP-1189: BSON Regex type 2014-11-21 Hannes Magnusson * PHP-1187: Implement BSON binary type 2014-11-21 Hannes Magnusson * Move the helpers up rather then in the middle of the vtable 2014-11-21 Hannes Magnusson * Fix some compiler warnings: (de-)constify 2014-11-20 Hannes Magnusson * bump libbson 2014-11-20 Hannes Magnusson * PHP-1188: Implement BSON code and code with scope types 2014-11-20 Hannes Magnusson * Fixed zts macros 2014-11-20 Hannes Magnusson * PHP-1191: Implement BSON timestamp type 2014-11-20 Hannes Magnusson * Fix arginfo and proto 2014-11-20 Hannes Magnusson * Fix test: Whoopsy. Missed the DONE section 2014-11-20 Hannes Magnusson * PHP-1194: Implement BSON MaxKey and MinKey types 2014-11-20 Hannes Magnusson * Bump libmongoc, and temporary switch to my fork with the needed patches 2014-11-20 Hannes Magnusson * Fixed PHP-1174: Implement WriteBatch::count() 2014-11-19 Hannes Magnusson * PHP-1190: Implement BSON\UTCDateTime 2014-11-19 Hannes Magnusson * PHP-1185: Add more Cursor related methods 2014-11-19 Hannes Magnusson * Fixed PHP-1185: Implement Cursor class 2014-11-19 Hannes Magnusson * PHP-1183: Implement default Iterator class for QueryResult & CommandResult 2014-11-19 Hannes Magnusson * Avoid compiler warnings 2014-11-19 Hannes Magnusson * Fixed PHP-1232: Implement the TODO 2014-11-19 Hannes Magnusson * Do not test the error messages from the server 2014-11-19 Hannes Magnusson * Tell PHP this is indeed an exposed stream that it doesn't have to worry about 2014-11-19 Hannes Magnusson * Fix memory leak when splitting a ns 2014-11-18 Hannes Magnusson * Make sure we have something to free 2014-11-04 Jeremy Mikola * Merge pull request #22 from hannesvdvreken/patch-1 2014-11-03 Hannes Van De Vreken * Typo in readme? "admit" instead of "admin" 2014-10-20 Hannes Magnusson * Merge pull request #21 from christkv/master 2014-10-20 Christian Kvalheim * Fixed build for OSX and llvm 2014-10-19 Jeremy Mikola * Rewrite README and document install/test process 2014-10-17 Jeremy Mikola * Merge pull request #18 from bjori/php1236-test-fixtures 2014-10-16 Jeremy Mikola * PHP-1180: Create make target to install Composer dependencies (for tests) 2014-08-05 Jeremy Mikola * Functional tests for sorted queries 2014-08-05 Jeremy Mikola * Use Faker to create user data fixtures 2014-08-05 Jeremy Mikola * Use require_once in skip test includes 2014-08-06 Jeremy Mikola * Use "phongo_test" as default test database 2014-08-06 Jeremy Mikola * Use preg_replace() for generating collection name from test file 2014-08-05 Jeremy Mikola * Clean up hex_dump() source and add citation 2014-10-03 Jeremy Mikola * Merge pull request #20 2014-10-03 Jeremy Mikola * PHP-1173: Use string "majority" for WriteConcern::MAJORITY 2014-10-03 Jeremy Mikola * Remove unused class properties in WriteConcern 2014-10-02 Jeremy Mikola * Merge pull request #19 from bjori/php1230-take-two 2014-10-02 Jeremy Mikola * PHP-1230: Clean up WriteResult property storage on WriteException 2014-09-30 Jeremy Mikola * Merge branch 'dry-run' 2014-09-30 Jeremy Mikola * Merge pull request #16 2014-09-29 Jeremy Mikola * Use correct return types for WriteResult-related init functions 2014-09-25 Jeremy Mikola * PHP-1142: Dump WriteResult object in write tests 2014-09-25 Jeremy Mikola * PHP-1142: Support upserted ids in WriteResult 2014-09-25 Jeremy Mikola * PHP-1142: Implement WriteResult getter for meta information 2014-09-25 Jeremy Mikola * PHP-1142: Memory cleanup and getters for WriteResult error zvals 2014-09-25 Jeremy Mikola * Fix tab indentation for generated C code 2014-09-24 Jeremy Mikola * Throw WriteException on failed write ops 2014-09-24 Jeremy Mikola * PHP-1230: Implement WriteException class 2014-09-24 Jeremy Mikola * Return exceptions after throwing in case we need to modify them 2014-09-24 Jeremy Mikola * PHP-1142: Init WriteError and WriteConcernError arrays for WriteResult 2014-09-24 Jeremy Mikola * PHP-1171: Move WriteConcernError init function to php_phongo.c 2014-09-24 Jeremy Mikola * PHP-1172: Implement WriteError class 2014-09-24 Jeremy Mikola * Fix typo in constant name 2014-09-23 Jeremy Mikola * Ensure libmongoc structs get freed in WriteBatch and WriteConcern 2014-09-18 Jeremy Mikola * Merge pull request #14 from bjori/php-1171-writeconcernerror 2014-09-17 Jeremy Mikola * PHP-1171: Implement WriteConcernError class 2014-09-05 Jeremy Mikola * Merge pull request #13 from bjori/php-1068 2014-09-05 Jeremy Mikola * PHP-1068: Test that CommandResult is iterable 2014-08-25 Jeremy Mikola * Merge pull request #12 2014-08-21 Jeremy Mikola * Always wrap query filter with $query modifier 2014-08-21 Jeremy Mikola * Use array helpers instead of hash iteration in Query option parsing 2014-08-21 Jeremy Mikola * Error if phongo_query_init() filter isn't array or object 2014-08-14 Jeremy Mikola * Use ZEND_STRS() when passing string/size arguments 2014-08-14 Jeremy Mikola * Fix setting of zvals with zend_hash_update() when constructing query 2014-08-11 Jeremy Mikola * Update tests for revised Query constructor API 2014-08-11 Jeremy Mikola * Change Query constructor args based on CRUD API spec 2014-08-11 Jeremy Mikola * Rename query document field in query struct 2014-08-22 Hannes Magnusson * bump submodules 2014-08-20 Hannes Magnusson * WS 2014-08-20 Hannes Magnusson * Fix segfault when no namespace is passed 2014-08-20 Hannes Magnusson * BSON: Fix serializing arrays inside of objects 2014-08-13 Hannes Magnusson * Move BSON encode/decode stuff into BSON namespace 2014-08-13 Hannes Magnusson * Enable a waterfall of compiler instructions for libbson and mongoc 2014-08-13 Hannes Magnusson * Supress the initialization output 2014-08-12 Hannes Magnusson * These dirs are required for all normal 'make' targets 2014-08-12 Hannes Magnusson * Overwrite the path to libbson that should be linked against 2014-08-12 Hannes Magnusson * debugging travis 2014-08-12 Hannes Magnusson * Build against bundled.. just not mongoc bundled 2014-08-12 Hannes Magnusson * Remove empty dir since there is nothing to make there 2014-08-12 Hannes Magnusson * Hack around mongo-c-driver not allowing us specify libbson location 2014-08-12 Hannes Magnusson * Link against libbson and make it available to mongo-c-driver 2014-08-12 Hannes Magnusson * Missed a file 2014-08-12 Hannes Magnusson * We submodule these now and automatically build it 2014-08-12 Hannes Magnusson * submodule mongo-c-driver and libbson and build it into phongo 2014-08-08 Hannes Magnusson * Fix zts 2014-08-08 Hannes Magnusson * Reduce mongoc stuff we compile and install 2014-08-08 Hannes Magnusson * Link against libmongoc-priv so we can go into the gory details 2014-08-06 Hannes Magnusson * Implement BSON\ObjectID properly 2014-08-04 Hannes Magnusson * Fix installing lcov 2014-07-31 Hannes Magnusson * Only skip it on travis 2014-07-30 Hannes Magnusson * CID-24876: Actually check for the return value and raise a warning now 2014-07-30 Hannes Magnusson * Simplify logging domain 2014-07-30 Hannes Magnusson * CID-39604: Fixed possible null dereferencing 2014-07-30 Hannes Magnusson * s/executeWrite/executeWriteBatch/g as the class is called WriteBatch 2014-07-30 Hannes Magnusson * Only collect and return the _id if requested - and never $this 2014-07-30 Hannes Magnusson * optimize BSON class' and allow ObjectID to have other then _id key 2014-07-30 Hannes Magnusson * Sprinkly tad bit more logging and fix coupleof protos 2014-07-30 Hannes Magnusson * Add json_to_bson() function 2014-07-30 Hannes Magnusson * Try properly to read as much data as requested 2014-07-30 Hannes Magnusson * Copy the oid 2014-07-30 Hannes Magnusson * Make BSON types implement BSON\Type interface 2014-07-22 Hannes Magnusson * Remove dirty hack and add a more dirty hack to fetch usable run-tests 2014-07-22 Hannes Magnusson * make sure a empty file doesn't break our build 2014-07-22 Hannes Magnusson * Don't run tests under valgrind on travis... bug in valgrind+libmongoc 2014-07-21 Hannes Magnusson * Install libmongoc using mci generated packages 2014-07-21 Hannes Magnusson * Fix bson buffer 2014-07-21 Hannes Magnusson * Implement WriteConcern 2014-07-21 Hannes Magnusson * new tests 2014-07-21 Hannes Magnusson * Fix zts 2014-07-21 Hannes Magnusson * Fix constant generator & regenerate 2014-07-21 Hannes Magnusson * Implement readPreferences 2014-07-21 Hannes Magnusson * Improve ignore paths 2014-07-21 Hannes Magnusson * Travis CI fixes 2014-07-19 Hannes Magnusson * fix path to ignore 2014-07-19 Hannes Magnusson * fix zts 2014-07-18 Hannes Magnusson * Add __toString() for ObjectID 2014-07-19 Hannes Magnusson * Returned generate _id when adding objects to batches 2014-07-19 Hannes Magnusson * Improve example 2014-07-19 Hannes Magnusson * Add ObjectID support 2014-07-19 Hannes Magnusson * Forgotten things for new classes 2014-07-18 Hannes Magnusson * Fix \0 in property names (private props, ...) 2014-07-18 Hannes Magnusson * Add the ability to automatically generate _id 2014-07-17 Hannes Magnusson * Better way to run the tests through valgrind 2014-07-18 Hannes Magnusson * Missing new class 2014-07-18 Hannes Magnusson * Add BSON objects and move generated classes into its own folders 2014-07-18 Jeremy Mikola * Only use GeneratedId for upserts, not inserts 2014-07-18 Jeremy Mikola * Replace createFromServers() factory method with getServers() 2014-07-17 Jeremy Mikola * Create WriteConcern value object 2014-07-17 Jeremy Mikola * Merge pull request #10 from bjori/make-testclean 2014-07-17 Jeremy Mikola * Replace clean-tests.sh with make target 2014-07-17 Hannes Magnusson * Run the tests under valgrind on travis 2014-07-17 Jeremy Mikola * Revise Manager::executeUpdate() error test 2014-07-17 Jeremy Mikola * Fix warning for bson_uint32_to_string() string pointer arg 2014-07-17 Jeremy Mikola * Shell script to clean up leftover test files 2014-07-16 Hannes Magnusson * Fix constants value 2014-07-16 Hannes Magnusson * Regenerate after coverity fixes 2014-07-17 Hannes Magnusson * Ignore the bundled zval array helper header 2014-07-16 Hannes Magnusson * tralalalllala. It really needs to be dedicated branch 2014-07-16 Hannes Magnusson * make clean first as it had already been built by compile.sh 2014-07-16 Hannes Magnusson * Get coverity to build the dry-run branch automatically 2014-07-16 Hannes Magnusson * I just learned about trap 2014-07-16 Hannes Magnusson * CID-24870: Unchecked return value from library 2014-07-16 Hannes Magnusson * CID-24872: Comment out not-yet-implemented code 2014-07-16 Hannes Magnusson * CID-24873: Unreachable code whoopsy! 2014-07-16 Hannes Magnusson * CID-24875: Fix uninitialized variable 2014-07-16 Hannes Magnusson * Avoid a deadcode warning from coverity 2014-07-16 Hannes Magnusson * Coverity link 2014-07-16 Hannes Magnusson * Update API listing 2014-07-16 Hannes Magnusson * Who doesn't like badges 2014-07-16 Hannes Magnusson * skip on travis.. 2014-07-16 Hannes Magnusson * Fix constants value 2014-07-16 Hannes Magnusson * Add a new none flag 2014-07-15 Hannes Magnusson * Generate all the C objects based on the PHP code 2014-07-15 Hannes Magnusson * Add the actual implementation into the PHP API docs 2014-07-15 Hannes Magnusson * Add a compare_objects handler for Server objects and always try to have a mongoc_host_t for it 2014-07-15 Hannes Magnusson * CS 2014-07-15 Hannes Magnusson * No need for this hack anymore 2014-07-15 Hannes Magnusson * We want latest and greatest mongodb 2014-07-15 Hannes Magnusson * Use bson_uint32_to_string() rather the spprintf() 2014-07-15 Hannes Magnusson * Fix the remaining tests 2014-07-15 Hannes Magnusson * Get tests to pass 2014-07-15 Hannes Magnusson * fix test 2014-07-14 Hannes Magnusson * fix tests 2014-07-14 Hannes Magnusson * whopsy 2014-07-14 Hannes Magnusson * revert accidental removal 2014-07-14 Hannes Magnusson * Revert accidental removal 2014-07-14 Hannes Magnusson * Extract the hint from the cursor 2014-07-14 Hannes Magnusson * No longer needed 2014-07-14 Hannes Magnusson * api changes 2014-07-14 Hannes Magnusson * Easier to maintain in a single file 2014-07-14 Hannes Magnusson * Regenerated 2014-07-14 Hannes Magnusson * Update bootsrapper 2014-07-14 Hannes Magnusson * Fix classname 2014-07-14 Hannes Magnusson * Add a zval array helper 2014-07-14 Hannes Magnusson * Add support for delete options 2014-07-09 Jeremy Mikola * PHP-1136: Allow custom cursor classes from command/query results 2014-07-09 Jeremy Mikola * Remove *.php from gitignore 2014-07-11 Hannes Magnusson * Initial Server implementation (as read-only object..) 2014-07-11 Hannes Magnusson * Fix test 2014-07-11 Hannes Magnusson * We have to save the results so they don't get posted to qa.php.net 2014-07-11 Hannes Magnusson * pretend object_properties_init() exists on PHP5.3 2014-07-11 Hannes Magnusson * Only run coveralls on success 2014-07-10 Hannes Magnusson * Fix zts 2014-07-10 Hannes Magnusson * Install libbson and libmongoc masters rather then releases 2014-07-10 Hannes Magnusson * Cosmetics and remove dead function 2014-07-10 Hannes Magnusson * Remove batch hacks & added single_[insert|update|delete] 2014-07-09 Hannes Magnusson * Touch up WriteResult as return value 2014-07-09 Hannes Magnusson * Fixed PHP-1138: Use Zend MM for libbson 2014-07-09 Hannes Magnusson * Fixed PHP-1137: Removed ugly private API hacks 2014-07-08 Hannes Magnusson * Return correct Result class 2014-07-08 Hannes Magnusson * Initialize optional arg as NULL 2014-07-08 Hannes Magnusson * Fix tests and push getServer() info down 2014-07-08 Hannes Magnusson * Remove no-longer valid classes 2014-07-08 Hannes Magnusson * Add ReadPreferences and full Query support 2014-07-08 Jeremy Mikola * Consolidate write result classes into WriteResult 2014-07-07 Jeremy Mikola * Add phpt files to gitignore 2014-07-07 Jeremy Mikola * Tests for constants and Server/Manager execute methods 2014-07-08 Hannes Magnusson * Fix calling continue in global scope 2014-07-08 Hannes Magnusson * Return MongoDB\Result when executing commands too 2014-07-03 Hannes Magnusson * print out our configure output 2014-07-03 Hannes Magnusson * Batch test and fix skipping test during cleanup phase 2014-07-03 Hannes Magnusson * Dead code 2014-07-03 Hannes Magnusson * Imlement batch execution 2014-07-03 Hannes Magnusson * FIXME: libmongoc workarounds... 2014-07-03 Hannes Magnusson * Fix type hint 2014-07-03 Hannes Magnusson * Missing batch ctor 2014-07-03 Hannes Magnusson * avoid bogus files showing up on coverage reports 2014-07-02 Hannes Magnusson * Simplify Batch interface 2014-07-02 Hannes Magnusson * See if this has any affect on coveralls.. 2014-07-02 Hannes Magnusson * we need newer lcov then howmany decades old the one in repo is 2014-07-02 Hannes Magnusson * Missing lcov on travis for coverage 2014-07-02 Hannes Magnusson * Bump to latest release 2014-07-02 Hannes Magnusson * guess the directory needs to exist 2014-07-02 Hannes Magnusson * Compile libmongoc from the src/ dir so we can steal the private header 2014-07-02 Hannes Magnusson * Rename it to _default so we don't conflict the actual defaults 2014-07-02 Hannes Magnusson * Make sure spl is loaded before we are in static builds 2014-07-02 Hannes Magnusson * fix zts 2014-07-02 Hannes Magnusson * Renamed error const 2014-07-02 Hannes Magnusson * Some zts fixes 2014-07-02 Hannes Magnusson * Fix building as a static extension 2014-07-02 Hannes Magnusson * ignore test files 2014-07-02 Hannes Magnusson * Simplify testing 2014-07-02 Hannes Magnusson * Better logging 2014-07-01 Hannes Magnusson * Return a result object and implement an iterator for it 2014-06-30 Hannes Magnusson * remove useless code 2014-06-30 Hannes Magnusson * rly? 2014-06-30 Hannes Magnusson * New class 2014-06-30 Hannes Magnusson * semicolon 2014-06-30 Hannes Magnusson * make it final and update to match the docs 2014-06-30 Hannes Magnusson * fqd 2014-06-30 Hannes Magnusson * wip query 2014-06-27 Hannes Magnusson * wip 2014-06-30 Hannes Magnusson * Add a generic result object that can be iterated over via iteratoraggregate 2014-06-30 Hannes Magnusson * This cursor needs a firstBatch, just like the CommandCursor 2014-06-27 Hannes Magnusson * fixed warnings and alloc 2014-06-27 Hannes Magnusson * blah 2014-06-27 Hannes Magnusson * wip 2014-06-26 Hannes Magnusson * Added logging to files and command executing 2014-06-24 Hannes Magnusson * Create a mongoc_client from URI 2014-06-24 Hannes Magnusson * More cruft for objects 2014-06-24 Hannes Magnusson * Remove duplicate include 2014-06-24 Hannes Magnusson * phongo api... 2014-06-24 Hannes Magnusson * Register default object handlers 2014-06-24 Hannes Magnusson * Add runtime error domain enum - and a wrapper to get exception type 2014-06-20 Hannes Magnusson * Fix zts 2014-06-20 Hannes Magnusson * Lets not enable developers flags on travis until we get a valid build first :) 2014-06-19 Hannes Magnusson * Add BSON tests 2014-06-18 Hannes Magnusson * Initial BSON implementation 2014-06-20 Hannes Magnusson * Fix include path 2014-06-20 Hannes Magnusson * Quick hack to install libmongoc on travis 2014-06-20 Hannes Magnusson * Add travis and coveralls support 2014-06-19 Hannes Magnusson * Update description per review from Jeremy 2014-06-19 Hannes Magnusson * Implement basics of phongo_exception_from_mongoc_domain() 2014-06-18 Hannes Magnusson * Implement the phongo_exception_from_phongo_domain() function 2014-06-18 Hannes Magnusson * Isolate all PHP compatability stuff into its own file 2014-06-18 Hannes Magnusson * PHP Extension CRUFT for phongo 2014-06-17 Hannes Magnusson * Add config.m4 2014-06-18 Hannes Magnusson * Skeleton implementation of the userland classes/methods 2014-06-18 Hannes Magnusson * Add .gitignore 2014-06-19 Hannes Magnusson * Add descriptions 2014-06-19 Hannes Magnusson * Merge pull request #5 from bjori/fix-query-flags 2014-06-19 Jeremy Mikola * Fix bit values for query flags 2014-06-17 Hannes Magnusson * Merge pull request #3 from bjori/docblocks 2014-06-16 Hannes Magnusson * Change some @see into @param or @param and add some descriptions 2014-06-16 Hannes Magnusson * Lets not start out with complicated zpp... 2014-06-16 Hannes Magnusson * Fix return value 2014-06-16 Hannes Magnusson * Fix docblock param order 2014-06-16 Hannes Magnusson * Add a bootstrapping file that includes all other files 2014-06-16 Hannes Magnusson * Pass through php -l 2014-06-16 Jeremy Mikola * Merge pull request #2 from bjori/split-classes 2014-06-13 Jeremy Mikola * Specity write options in execute methods, not batch constructors 2014-06-13 Jeremy Mikola * Command execution takes a database name, not a namespace 2014-06-13 Jeremy Mikola * Add cursor flag constants 2014-06-12 Jeremy Mikola * Implement review feedback 2014-06-12 Jeremy Mikola * Split API classes and interfaces 2014-05-14 Derick Rethans * Fixed unintialized variable 2014-05-13 Hannes Magnusson * The CRUD examples are now multiple separate files 2014-05-13 Hannes Magnusson * Merge pull request #1 from bjori/split-crud 2014-05-13 Jeremy Mikola * Query constructor should take query object, not just criteria 2014-05-13 Jeremy Mikola * Use value objects and make QueryResult IteratorAggregate 2014-05-13 Jeremy Mikola * Split and modify CRUD examples 2014-05-06 Hannes Magnusson * Add basic .gitignore 2014-05-06 Hannes Magnusson * Initial draft of suggested API 2014-05-06 Hannes Magnusson * Example of a wishful API 2014-05-06 Hannes Magnusson * Initial commit mongodb-1.1.5/RELEASE-1.00000664000175000017500000006774412673034026014327 0ustar jmikolajmikolaRELEASE 1.0.0 ------------- 2015-10-30 Jeremy Mikola * Bump extension version to 1.0.0 2015-10-30 Jeremy Mikola * PHPC-475: toJSON and fromJSON should thrown on error 2015-10-28 Jeremy Mikola * Tests for fromJSON() and toJSON() 2015-10-26 Jeremy Mikola * Back to -dev 2015-10-26 Jeremy Mikola * Add 1.0.0RC0 release notes RELEASE 1.0.0RC0 ------------- 2015-10-26 Jeremy Mikola * Bump extension version to 1.0.0RC0 2015-10-26 Jeremy Mikola * Revise system libbson version check error message 2015-10-23 Jeremy Mikola * Update GitHub URLs for org change and repo rename 2015-10-21 Jeremy Mikola * PHPC-465: Remove WriteConcernException and WriteErrorException 2015-10-21 Jeremy Mikola * Rename WriteConcernError tests 2015-10-21 Jeremy Mikola * PHPC-465: Remove Manager's single write methods 2015-10-20 Jeremy Mikola * PHPC-440: WriteErrorException extends abstract WriteException 2015-10-20 Jeremy Mikola * PHPC-462: Remove unused DuplicateKeyException 2015-10-19 Jeremy Mikola * PHPC-310: Make BSON types final and disable serialization for now 2015-10-19 Jeremy Mikola * Make BSON create_object assignments consistent 2015-10-16 Jeremy Mikola * PHPC-310: Exception classes need not be final 2015-10-15 Jeremy Mikola * PHPC-444: Support options array in BulkWrite and executeInsert() 2015-10-15 Jeremy Mikola * Fix indentation 2015-10-14 Jeremy Mikola * PHPC-407: Rename X509 error test and fix cert path 2015-10-14 Jeremy Mikola * Rename X509 connection tests 2015-10-14 Jeremy Mikola * PHPC-454: Remove WriteResult::getInfo() method 2015-10-14 Jeremy Mikola * PHPC-441: slaveOk bit is now set on hinted secondary query 2015-10-14 Jeremy Mikola * Bump libbson and libmongoc submodules to 1.2.0 2015-10-07 Hannes Magnusson * PHPC-256: Productions debug logs 2015-10-07 Hannes Magnusson * PHPC-441: Skip (xfail) these tests while the ticket is being worked on 2015-10-07 Hannes Magnusson * Make sure we have the X509 declaration we need 2015-10-07 Hannes Magnusson * No need for TSRMLS here -- no calls to PHP at all 2015-10-06 Jeremy Mikola * Back to -dev 2015-10-06 Jeremy Mikola * Update install examples to mongodb-beta 2015-10-06 Jeremy Mikola * Add 1.0.0beta2 release notes RELEASE 1.0.0beta2 ------------- 2015-10-06 Jeremy Mikola * Avoid nested macros when reporting runtime version in debug mode 2015-10-05 Jeremy Mikola * Omit merge commits from release changelog 2015-10-05 Jeremy Mikola * Use UTC time when creating package.xml 2015-10-05 Jeremy Mikola * Bump extension version to 1.0.0beta2 2015-10-05 Remi Collet * PHPC-442: report PHP version in debug info 2015-10-05 Remi Collet * report runtime version in debug mode 2015-10-05 Remi Collet * rename macros 2015-10-04 Remi Collet * report libraries runtime versions 2015-10-05 Jeremy Mikola * Test write and WC error extraction for single write methods 2015-10-02 Jeremy Mikola * PHPC-409: $readPreference is no longer sent to non-mongos nodes 2015-10-02 Jeremy Mikola * Update filenames for libmongoc and libbson version functions 2015-10-02 Jeremy Mikola * PHPC-438: Debug handler should display null for no WC error 2015-10-02 Jeremy Mikola * PHPC-436: Handle new writeConcernErrors array in mongoc_write_result_t 2015-10-02 Jeremy Mikola * Bump libbson and libmongoc submodules to 1.2.0-rc0 2015-09-11 Hannes Magnusson * PHPC-415: Add testcase 2015-09-11 Hannes Magnusson * PHPC-415: SSL/TLS already set-up for this stream 2015-09-09 Hannes Magnusson * $readPreferences should not be sent to standalone server 2015-09-09 Hannes Magnusson * Don't provide server_id when we have none 2015-10-01 Jeremy Mikola * Use versioned URI for mongo-orchestration 2015-10-01 Jeremy Mikola * Increase mongo-orchestration HTTP timeout 2015-08-20 Jeremy Mikola * Empty query results should still pass "find" phase in mo-tests 2015-08-20 Jeremy Mikola * Implement "clientHosts" phase for mo-tests 2015-08-19 Jeremy Mikola * Support "delete" operation in mo-tests 2015-08-19 Jeremy Mikola * Rename "findOne" to "find" in mo-tests 2015-08-19 Jeremy Mikola * Fix exception throwing in mo-tests conversion script 2015-09-24 Jeremy Mikola * PHPC-393: Ignore non-public properties when encoding BSON 2015-09-24 Jeremy Mikola * Previous break statement makes the else condition redundant 2015-09-23 Jeremy Mikola * PHPC-430, PHPC-377: Do not convert Query filter arg to an object 2015-08-27 Hannes Magnusson * PHPC-377: Eliminate object casting and whole lot of zend hash helpers 2015-08-25 Hannes Magnusson * PHPC-373: Get rid of MAKE_STD_ZVAL() and use bson_t instead 2015-09-23 Jeremy Mikola * PHPC-430: Regression tests for Query arg corruption 2015-09-23 Jeremy Mikola * PHP versions in .travis.yml don't need to be strings 2015-08-27 Hannes Magnusson * PHPC-379: I broke PHP5.3 build. Thats OK, since we don't support it. 2015-09-23 Jeremy Mikola * PHPC-427: Fix parsing of null WC journal param for PHP 5.4 2015-09-22 Jeremy Mikola * PHPC-428: Remove support for WriteConcern fsync option 2015-09-22 Jeremy Mikola * Update arg info for WriteConcern $w ctor parameter 2015-09-21 Jeremy Mikola * PHPC-427: Do not set WC journal/fsync to false for NULL args 2015-09-18 Jeremy Mikola * Additional tests for WriteConcern debug handler 2015-09-18 Jeremy Mikola * PHPC-423: WriteConcern should report default "w" option as null 2015-09-17 Jeremy Mikola * PHPC-426: WC ctor should throw for invalid $w and $wtimeout args 2015-09-17 Jeremy Mikola * PHPC-425: WC ctor should accept int/string $w args w/o casting 2015-09-17 Jeremy Mikola * WriteConcern ctor error test doesn't need EXPECTF 2015-09-17 Jeremy Mikola * Use throws() helper function in WriteConcern ctor error test 2015-09-18 Derick Rethans * Skip logging tests for HHVM, which will use its own method 2015-09-10 Derick Rethans * Better messages for when things go wrong with exceptions 2015-09-10 Derick Rethans * PHPC-412: HHVM does not do SSL peer verification like PHP 2015-09-18 Jeremy Mikola * PHPC-410: Make BSON exception message consistent with HHVM 2015-09-17 Jeremy Mikola * Split out UTCDateTime toDateTime and toString tests 2015-09-15 Jeremy Mikola * PHPC-410: zval_to_bson() should throw on non-Serializable Type objects 2015-09-15 Jeremy Mikola * PHPC-410: object_to_bson() should throw on unsupported BSON\Type objects 2015-09-09 Jeremy Mikola * PHPC-410: object_to_bson() should encode non-stdClass objects 2015-09-09 Jeremy Mikola * Revise debug messages in object_to_bson() 2015-09-16 Jeremy Mikola * PHPC-418: Getters for WriteConcern properties 2015-09-16 Jeremy Mikola * Rename WriteConcern tests 2015-09-16 Jeremy Mikola * Move PHONGO_WRITE_CONCERN_W_MAJORITY definition to php_phongo.h 2015-09-15 Jeremy Mikola * Revise ReadPreference constructor error messages 2015-09-15 Jeremy Mikola * Rename first ReadPreference constructor arg to "mode" 2015-09-15 Jeremy Mikola * PHPC-418: Getters for ReadPreference properties 2015-09-15 Jeremy Mikola * Use valid tag sets in ReadPreference tests 2015-09-15 Jeremy Mikola * Rename ReadPreference tests and split constructor error test 2015-09-15 Jeremy Mikola * PHPC-417: Return value objects from Manager RP/WC getters 2015-09-15 Jeremy Mikola * Declare phongo_cursor_init() statically 2015-09-09 Jeremy Mikola * PHPC-408: Ensure object_to_bson() always creates a BSON document 2015-09-09 Jeremy Mikola * Refactor bson-utcdatetime-001.phpt 2015-09-10 Jeremy Mikola * Back to -dev 2015-09-10 Jeremy Mikola * Add 1.0.0beta1 release notes RELEASE 1.0.0beta1 ------------- 2015-09-10 Jeremy Mikola * Bump extension version to 1.0.0beta1 2015-09-09 Jeremy Mikola * Merge pull request #98 2015-09-09 Jeremy Mikola * PHPC-381: Print whether profile commands were successful 2015-09-02 Jeremy Mikola * PHPC-381: Server::executeQuery/Command() should take a read preference 2015-09-04 Jeremy Mikola * Include unknown error domain in log messages 2015-09-02 Jeremy Mikola * Fall back to driver's RuntimeException instead of SPL 2015-09-04 Hannes Magnusson * Merge pull request #100 from bjori/master 2015-09-04 Hannes Magnusson * s/10gen-labs/mongodb-labs/g after org changes 2015-09-03 Hannes Magnusson * Merge pull request #99 from bjori/master 2015-08-20 Hannes Magnusson * Bump libmongoc to 1.2-beta1 2015-09-02 Derick Rethans * Merged pull request #95 2015-09-02 Derick Rethans * Disable the test for a double wrap with IteratorIterator() 2015-09-02 Derick Rethans * Disable test that dumps hex codes for generated BSON 2015-09-02 Derick Rethans * Merged pull request #96 2015-09-02 Derick Rethans * Fixed getServers test to include milliseconds in UTCDate dumps 2015-09-02 Jeremy Mikola * Merge pull request #92 2015-08-30 Jeremy Mikola * Clean up BSON error tests 2015-09-01 Jeremy Mikola * Merge pull request #80 2015-08-14 Jeremy Mikola * PHPC-361: Manager::getServers() should omit unknown servers 2015-09-01 Derick Rethans * Merged pull request #91 2015-08-28 Derick Rethans * HHVM encodes __pclass last, so disable these tests here. 2015-08-26 Derick Rethans * phpinfo() behaves totally different in HHVM 2015-08-28 Derick Rethans * Merged pull request #89 2015-08-27 Derick Rethans * HHVM does not allow for current() on an object 2015-08-27 Derick Rethans * Split tests for invalid arguments out into their own files, and ignore them for HHVM 2015-08-28 Jeremy Mikola * Merge pull request #88 2015-08-26 Jeremy Mikola * PHPC-337: BSON\Javascript debug handler 2015-08-26 Jeremy Mikola * PHPC-339: BSON\Timestamp debug handler 2015-08-26 Jeremy Mikola * PHPC-340: BSON\UTCDateTime debug handler 2015-08-26 Jeremy Mikola * PHPC-338: BSON\Regex debug handler 2015-08-26 Jeremy Mikola * Fix test expectation for builds with top-level BSON namespace 2015-08-21 Jeremy Mikola * Merge pull request #85 2015-08-21 Hannes Magnusson * Don't be printing out these commands during execution 2015-08-21 Hannes Magnusson * Back to -dev 2015-08-21 Hannes Magnusson * PHPC-366: Update release script to use RELEASE-x.y file 2015-08-21 Hannes Magnusson * PHPC-366: Merge 1.0.x release notes into RELEASE-1.0 2015-08-21 Hannes Magnusson * PHPC-366: Merge RELEASE-0.* release notes into RELEASE-0 2015-08-20 Jeremy Mikola * Add 1.0.0alpha2 release notes RELEASE 1.0.0alpha2 -------------- 2015-08-20 Jeremy Mikola * Bump extension version to 1.0.0alpha2 2015-08-20 Jeremy Mikola * Merge pull request #84 2015-08-20 Jeremy Mikola * PHPC-365: Add src/contrib to Windows build includes 2015-08-20 Jeremy Mikola * Merge pull request #81 RELEASE 1.0.0alpha1 -------------- 2015-08-18 Jeremy Mikola * Bump extension version to 1.0.0alpha1 2015-08-18 Jeremy Mikola * Bump minimum PHP version requirement to 5.4 2015-08-18 Jeremy Mikola * Use php.net email addresses for authors 2015-08-20 Hannes Magnusson * Link to the HHVM project 2015-08-20 Hannes Magnusson * Test running belongs to CONTRIBUTING.md 2015-08-20 Hannes Magnusson * Add docs for the new PHONGO_SERVERS environment variable 2015-08-20 Hannes Magnusson * We don't tail master 2015-08-20 Hannes Magnusson * Merge pull request #82 from derickr/test-name-and-servers 2015-08-20 Derick Rethans * Do this with an env var instead 2015-08-19 Jeremy Mikola * Fix str_replace() newline replacement 2015-08-19 Derick Rethans * Allow for PHONGO-SERVERS.json in ~ (and fix a test case name) 2015-08-14 Jeremy Mikola * Merge pull request #76 2015-08-14 Jeremy Mikola * Strip newlines from exception messages for more concise failures 2015-08-05 Derick Rethans * Added the error message to the failure cases. 2015-08-14 Jeremy Mikola * Merge pull request #70 2015-08-14 Jeremy Mikola * Add mongoc-host-list.c to config sources 2015-08-14 Jeremy Mikola * Fix indentation in config.m4 sources 2015-08-14 Jeremy Mikola * Bump libmongoc submodule to 1.2.0-beta 2015-07-30 Jeremy Mikola * Restore -Werror compile flag for 5.4+ developer builds 2015-08-14 Jeremy Mikola * Merge pull request #78 2015-08-07 Jeremy Mikola * PHPC-271: Server::executeBulkWrite() should take a write concern 2015-08-13 Jeremy Mikola * Merge pull request #77 2015-08-05 Jeremy Mikola * Split out Manager constructor error tests 2015-08-05 Jeremy Mikola * Manager should check client pointer before destroying it 2015-08-03 Jeremy Mikola * PHPC-196: Implement Manager getters for WC and RP 2015-08-05 Jeremy Mikola * PHPC-353: Return early when there are no options to apply 2015-08-05 Jeremy Mikola * PHPC-353: Support RP and WC in Manager options array 2015-08-05 Jeremy Mikola * Manager constructor should check if URI or client creation fails 2015-07-31 Jeremy Mikola * Fix memory leak in _phongo_debug_bson() 2015-08-13 Jeremy Mikola * Merge pull request #79 2015-08-13 Jeremy Mikola * Trim #includes, since src/contrib is already an include path 2015-08-05 Jeremy Mikola * Merge pull request #75 2015-08-05 Jeremy Mikola * PHPC-357: Revise test and relocate to standalone group 2015-08-04 Derick Rethans * PHPC-357: "invalid namespace" exception should report the namespace 2015-08-05 Jeremy Mikola * Merge pull request #74 2015-08-04 Derick Rethans * PHPC-129: Split out WriteConcern constructor error test 2015-08-04 Derick Rethans * Merged pull request #73 2015-08-03 Derick Rethans * Rename BSON\Binary's subType field and getSubType() method to type and getType() 2015-08-04 Derick Rethans * Merged pull request #72 2015-07-31 Derick Rethans * Temporary fix for the NULL vs null issue 2015-08-03 Hannes Magnusson * Make the relative path work 2015-08-03 Hannes Magnusson * Skip test when not using the test vms 2015-07-30 Jeremy Mikola * Merge pull request #69 2015-07-30 Jeremy Mikola * PHPC-350: Bump libmongoc submodule for updated headers 2015-07-30 Jeremy Mikola * Merge pull request #68 2015-07-30 Jeremy Mikola * bson_to_zval() should always initialize state->zchild 2015-07-29 Jeremy Mikola * Update extension filename in Travis scripts 2015-07-29 Jeremy Mikola * PHPC-347: bson_to_zval() leaks when buffer contains no documents 2015-07-29 Jeremy Mikola * PHPC-345: bson_to_zval() should throw exceptions instead of warnings 2015-07-29 Jeremy Mikola * Merge pull request #67 2015-07-28 Jeremy Mikola * PHPC-334: Split hex_dump() test case 2015-07-29 Jeremy Mikola * Merge pull request #64 2015-07-27 Jeremy Mikola * PHP 5.3 compatibility for tools.php 2015-07-27 Jeremy Mikola * Define str_efree() macro for PHP 5.3 compatibility 2015-07-27 Jeremy Mikola * Compile with no-cast-qual for PHP 5.3 2015-07-27 Jeremy Mikola * PHPC-344: Allow non-root Serializable to encode as BSON array 2015-07-27 Jeremy Mikola * PHPC-343: Allow bsonSerialize() to return a stdClass 2015-07-27 Jeremy Mikola * PHPC-331: Tests for BSON deserialization errors 2015-07-27 Jeremy Mikola * PHPC-329: bson_to_zval() serialization spec compatibility 2015-07-27 Jeremy Mikola * PHPC-329: __pclass must be both instantiatable and Persistable 2015-07-27 Jeremy Mikola * PHPC-329: Apply more validation to type map class 2015-07-24 Jeremy Mikola * PHPC-336: BSON\Binary debug handler 2015-07-28 Jeremy Mikola * Merge pull request #66 2015-07-28 Derick Rethans * Assert what the tests want, and not more 2015-07-28 Derick Rethans * HHVM does not include the function name, and has two lines of extra stack trace 2015-07-24 Jeremy Mikola * Merge pull request #63 2015-07-24 Jeremy Mikola * PHPC-341: Ensure bson_t is freed after decoding JSON 2015-07-22 Jeremy Mikola * Merge pull request #62 2015-07-22 Jeremy Mikola * PHPC-333: Implement MongoDB\BSON\Binary::getData() 2015-07-22 Jeremy Mikola * Fix proto for Binary::getSubType() 2015-07-22 Jeremy Mikola * Merge pull request #59 2015-07-15 Hannes Magnusson * bump debug tests after slight tracing changes 2015-07-15 Hannes Magnusson * PHPC-229: Support options array in second parameter of Manager ctor 2015-07-22 Jeremy Mikola * Merge pull request #61 2015-07-21 Jeremy Mikola * PHPC-334: Don't produce BSON with multiple __pclass fields 2015-07-21 Jeremy Mikola * Merge pull request #60 2015-07-21 Jeremy Mikola * Don't build with -Werror until CDRIVER-757 is resolved 2015-07-20 Jeremy Mikola * PHPC-330: Always include __pclass property when unserializing BSON 2015-07-15 Hannes Magnusson * Add -Werror into --enable-developer-flags 2015-07-15 Hannes Magnusson * Move the php_array to contrib/ and rename to _api 2015-07-14 Hannes Magnusson * We are tracking 1.2.0-dev, not master! 2015-07-15 Jeremy Mikola * Merge pull request #56 2015-07-11 Jeremy Mikola * Use namespace-agnostic BSON (de)serialization functions 2015-07-11 Jeremy Mikola * Fix from/toJSON() protos 2015-07-11 Jeremy Mikola * PHPC-311: Rename from/toArray() functions to from/toPHP() 2015-07-10 Jeremy Mikola * PHPC-315: Support "root" type mapping for top-level documents 2015-07-06 Jeremy Mikola * PHPC-319: Convert top-level documents to stdClass by default 2015-07-07 Jeremy Mikola * Relax expected class instance in Manager: getServers() test 2015-07-07 Jeremy Mikola * Use plural property name to store list of Address objects 2015-07-07 Jeremy Mikola * Fix WriteResult::getWriteConcernError() proto 2015-07-08 Hannes Magnusson * Force 'E' to be present in php.ini so environment variables are picked up 2015-07-07 Hannes Magnusson * The MongoDB 3.0 repo was moved. 2015-07-07 Hannes Magnusson * Don't start/stop servers on travis. We don't use MO here yet 2015-07-07 Hannes Magnusson * PHPC-304: Enable the test again -- and fix typo in the clean section! 2015-07-07 Hannes Magnusson * Add the START() servers to PHONGO-SERVERS, and remove it with DELETE() 2015-07-07 Hannes Magnusson * PHPC-303: Cannot connect to healthy Replica Set if seedlist only contains a secondary 2015-07-07 Jeremy Mikola * Merge pull request #57 2015-07-06 Jeremy Mikola * PHPC-325: bson_to_zval() leaks when buffer contains multiple documents 2015-07-06 Jeremy Mikola * Merge pull request #55 2015-06-17 Jeremy Mikola * PHPC-306: Check for sasl_client_done in config.m4 2015-07-01 Jeremy Mikola * Update expected float output after libbson bump 2015-07-01 Jeremy Mikola * Bump libbson and libmongoc submodules 2015-07-06 Jeremy Mikola * Merge pull request #51 2015-07-06 Jeremy Mikola * Remove redundant array conversions in phongo_query_init() 2015-07-06 Jeremy Mikola * PHPC-317: Ensure "sort" query option serializes as BSON object 2015-06-30 Hannes Magnusson * PHPC-323: The check for system mongoc checks system bson, not mongoc 2015-06-30 Hannes Magnusson * PHPC-322: Wrong bugtracker URL in configure output 2015-06-30 Hannes Magnusson * PHPC-321: UTCDatetime -> UTCDateTime 2015-06-30 Hannes Magnusson * PHPC-321: UTCDatetime -> UTCDateTime 2015-06-30 Hannes Magnusson * PHPC-309: Bump tests 2015-06-30 Hannes Magnusson * PHPC-309: Move the BSON namespace under MongoDB\ namespace 2015-06-30 Jeremy Mikola * Merge pull request #50 from 10gen-labs/jmikola-patch-1 2015-06-29 Jeremy Mikola * Merge pull request #49 2015-06-21 Jeremy Mikola * LDAP VM does not require python-pip (or epel) 2015-06-29 Jeremy Mikola * Merge pull request #53 2015-06-29 Jeremy Mikola * PHPC-308: Skip getmore test until libmongoc issues are resolved 2015-06-21 Jeremy Mikola * Update install docs, since we now have a PECL package 2015-06-09 Hannes Magnusson * bump submodule, hopfully fixing build 2015-06-09 Hannes Magnusson * Fix build after some SDAM changes 2015-06-09 Hannes Magnusson * install mongo-c-driver required building blocks 2015-06-09 Hannes Magnusson * PHPC-308: Failed getmore should throw exception 2015-05-22 Hannes Magnusson * There is no need for these tests to be this slow -- safes 2seconds now 2015-05-22 Hannes Magnusson * Cluster tests are slow 2015-05-20 Hannes Magnusson * Fix test -- this isn't a hardcoded ID 2015-05-20 Hannes Magnusson * Move MO host resolving to tools 2015-05-20 Hannes Magnusson * PHPC-304: Add a failGetMore trigger 2015-05-20 Hannes Magnusson * PHPC-291: New cluster/socket/connection tests 2015-05-20 Hannes Magnusson * PHPC-291: Add a script to convert mo-tests (JSON) to PHPT 2015-05-20 Hannes Magnusson * These are no longer used 2015-05-18 Hannes Magnusson * Organize cursor tests 2015-05-20 Hannes Magnusson * Merge pull request #46 from remicollet/issue-driver 2015-05-20 Remi Collet * PHPC-305: add --with-libmongo option 2015-05-18 Hannes Magnusson * Add a helper to know if we are in predictable (vagrant) env or not 2015-05-18 Hannes Magnusson * Fix server IDs 2015-05-13 Hannes Magnusson * Improve code coverage for the WriteException 2015-05-13 Hannes Magnusson * Add test for the info/ini section 2015-05-13 Hannes Magnusson * Improve code covergae 2015-05-13 Hannes Magnusson * PHPC-75: Improve debug output coverage 2015-05-13 Hannes Magnusson * Use the defines 2015-05-13 Hannes Magnusson * fix test after moving it around 2015-05-13 Hannes Magnusson * PHPC-75: Improve coverage 2015-05-13 Hannes Magnusson * improve code coverage 2015-05-13 Hannes Magnusson * Improve test organization 2015-05-13 Hannes Magnusson * PHPC-75: Server error code coverage 2015-05-13 Hannes Magnusson * Fix test on travis 2015-05-13 Hannes Magnusson * PHPC-301: var_dump()ing Manager should show debug info 2015-05-13 Hannes Magnusson * PHPC-300: Add var_dump() debug info for Server 2015-05-13 Hannes Magnusson * PHPC-75: Improve coverage for the Manager 2015-05-13 Hannes Magnusson * PHPC-277: Ensure Query always serializes $query as a BSON object 2015-05-13 Hannes Magnusson * Split the test into success/failure 2015-05-13 Hannes Magnusson * PHPC-299: Annoying compiler warning 2015-05-13 Hannes Magnusson * PHPC-298: Coalesce small writes 2015-05-13 Hannes Magnusson * PHPC-284: Fix LogicException declaration 2015-05-12 Hannes Magnusson * bump submodules 2015-05-12 Hannes Magnusson * PHPC-279: Add 2.4 (and 2.6) to build matrix and ensure test suite compatibility 2015-05-06 Hannes Magnusson * PHPC-296: phongo.debug created for empty values 2015-05-06 Hannes Magnusson * Bump version mongodb-1.1.5/RELEASE-1.10000664000175000017500000004650212673034026014315 0ustar jmikolajmikolaRELEASE 1.1.4 ------------- 2016-03-10 Jeremy Mikola * Bump extension version to 1.1.4 2016-03-09 Jeremy Mikola * PHPC-620: Lowercase hexadecimal strings in ObjectID ctor 2016-03-09 Jeremy Mikola * Fix test title 2016-03-09 Jeremy Mikola * PHPC-623: Fix 64-bit integer conversion for BSON keys 2016-03-04 Jeremy Mikola * Back to -dev 2016-03-04 Jeremy Mikola * Add 1.1.3 release notes RELEASE 1.1.3 ------------- 2016-03-04 Jeremy Mikola * Bump extension version to 1.1.3 2016-03-03 Jeremy Mikola * Skip PHPC-545 test on HHVM due to __pclass encoding order 2016-03-02 Jeremy Mikola * Improve comment in bson-toJSON_error-001.phpt 2016-03-02 Jeremy Mikola * PHPC-613: toJSON() should throw if bson_as_json() fails 2016-03-02 Jeremy Mikola * PHPC-615: Return after throwing for bson_reader_read() error 2016-03-02 Jeremy Mikola * PHPC-616: Document and array visitors should throw for corrupt BSON 2016-03-02 Jeremy Mikola * PHPC-531: Fix double free in corrupt BSON visitor 2016-03-02 Jeremy Mikola * toPHP() regression tests for bson_reader_read() errors 2016-03-02 Jeremy Mikola * Prevent duplication and reduce strlen() usage 2016-03-01 Derick Rethans * Fixed PHPC-506: Use more descriptive messages in WriteExceptions 2016-02-25 Jeremy Mikola * PHPC-414: Combine 32-bit and 64-bit UTCDateTime debug handler tests 2016-02-26 Jeremy Mikola * PHPC-593: Binary type is an unsigned 8-bit integer 2016-02-26 Jeremy Mikola * PHPC-594: Timestamp components are unsigned 32-bit integers 2016-02-26 Jeremy Mikola * PHPC-595: Throw exception if wtimeout > INT32_MAX 2016-02-25 Jeremy Mikola * Use INT32 limit constants instead of INT/LONG 2016-02-25 Jeremy Mikola * PHPC-544: Use phongo_long in UTCDateTime ctor 2016-02-25 Jeremy Mikola * PHPC-544: Consult SIZEOF_ZEND_LONG for 64-bit integer support 2016-02-25 Jeremy Mikola * Remove unused macro, which is already defined in libbson 2016-02-25 Jeremy Mikola * PHPC-592: ADD_ASSOC_STRINGL() can only be used with string literals 2016-02-29 Jeremy Mikola * Revert "Merge pull request #241" 2016-02-24 Jeremy Mikola * wip 2016-02-24 Jeremy Mikola * Fix whitespace 2016-02-22 Jeremy Mikola * Fix BulkWrite::update() "multi" option usage in docs 2016-02-12 Jeremy Mikola * PHPC-545: Regression test for Peristable bug report 2016-02-09 Jeremy Mikola * PHPC-550: Always encode ODS field when serializing Persistable documents 2016-02-09 Jeremy Mikola * Regression test for executing BulkWrite multiple times 2016-02-10 Jeremy Mikola * Fix test title 2016-02-10 Jeremy Mikola * Tests should use and cleanup their own collection 2016-02-12 Jeremy Mikola * PHPC-581: Use ConnectionTimeoutException for server selection failures 2016-02-12 Jeremy Mikola * PHPC-582: Manager::selectServer() should select exception class based on bson_error_t 2016-02-12 Jeremy Mikola * PHPC-553: Relax expected output patterns for HHVM 2016-02-12 Jeremy Mikola * PHPC-553: Check for connection exceptions in exec and SS methods 2016-02-04 Jeremy Mikola * PHPC-553: Suppress warnings during stream creation 2016-02-12 Jeremy Mikola * PHPC-566: Remove request_id from Manager::__debugInfo() 2016-02-12 Jeremy Mikola * PHPC-567: Bump config.m4 library deps 2016-02-12 Jeremy Mikola * PHPC-567: Upgrade libbson and libmongoc to 1.3.3 2016-02-12 Derick Rethans * Skip this test on HHVM, as its DateTime class is ancient and behaves differently 2016-02-10 Jeremy Mikola * PHPC-523: Parse readconcernlevel in URI options array 2016-02-10 Jeremy Mikola * PHPC-563: Remove undocumented Manager "hosts" URI option 2016-02-02 Jeremy Mikola * PHPC-539: Include read concern in Query debug output 2016-02-09 Jeremy Mikola * Regression test for extending final classes 2016-02-09 Jeremy Mikola * PHPC-519: Add missing modifiers to final class methods 2016-02-08 Jeremy Mikola * PHPC-538: ObjectID should not abort on null ctor arg 2016-02-02 Jeremy Mikola * PHPC-515: Test that negative cursor limits return one batch 2016-01-20 Derick Rethans * Fixed PHPC-543: MongoDB\BSON\UTCDateTime on 32 bit platforms parse argument wrong 2016-02-02 Derick Rethans * Fixed PHPC-558: Upgrade libmongoc and libbson to 1.3.2 2016-02-02 Jeremy Mikola * Remove Manager::executeInsert() usage in ODS docs 2016-01-12 Derick Rethans * Skip and fix test for HHVM with ReadConcerns 2016-01-07 Jeremy Mikola * Back to -dev 2016-01-07 Jeremy Mikola * Add 1.1.2 release notes RELEASE 1.1.2 ------------- 2016-01-07 Jeremy Mikola * Bump extension version to 1.1.2 2016-01-06 Jeremy Mikola * PHPC-496: Revert "Temporary workaround for warning in mongoc" 2016-01-06 Jeremy Mikola * Improve other config.m4 check messages 2015-12-31 Lior Kaplan * PHPC-534: Enable configure without SASL and support --with-mongodb-sasl=no 2015-12-31 Lior Kaplan * Improve SASL check message 2015-12-31 Lior Kaplan * Don't print pcre-dir usage during configure check 2016-01-01 Jeremy Mikola * PHPC-529: Prefix BSON functions to avoid symbol conflicts 2015-12-30 Jeremy Mikola * phongo_bson_append() can be static and get zval type internally 2015-12-30 Jeremy Mikola * PHPC-528: Support zval references when appending BSON 2015-12-30 Remi Collet * PHPC-527: fix call to add_index_stringl 2015-12-26 Remi Collet * PHPC-527: Fix PHP 7 / 32bits build 2015-12-22 Jeremy Mikola * Back to -dev 2015-12-22 Jeremy Mikola * Add 1.1.1 release notes RELEASE 1.1.1 ------------- 2015-12-22 Jeremy Mikola * Bump extension version to 1.1.1 2015-12-22 Jeremy Mikola * PHPC-285: Allow for PHP 7.x support in package.xml 2015-12-16 Jeremy Mikola * Fix protos for ReadPreference and WriteConcern 2015-12-22 Kanin Peanviriyakulkit * Remove "beta" in doc. 2015-12-21 Jeremy Mikola * PHPC-285: VC14 needs timezone defined for SSL function 2015-12-21 Jeremy Mikola * PHPC-285: Fix syntax for empty struct initializer 2015-12-18 Derick Rethans * Fixed test case, where PHP 5 and PHP 7 call the type differently 2015-12-18 Derick Rethans * Fixed 'dump on uninitialised value' with BSON deserialisation 2015-12-16 Derick Rethans * Fixed issues with PHP 7 and the new ReadConcern 2015-12-18 Derick Rethans * Fixed CS from Joe's patch 2015-12-14 Joe Watkins * fix leaks and logical errors for PHP 7 2015-11-07 Jeremy Mikola * PHPC-400: Compare WriteConcern journal arg with IS_TRUE 2015-11-07 Jeremy Mikola * PHPC-405: Additional zval* to zval changes 2015-11-07 Jeremy Mikola * PHPC-397: Additional RETURN_STRING updates 2015-11-07 Jeremy Mikola * PHPC-393: Don't BSON-encode non-public properties in PHP 7 2015-11-07 Jeremy Mikola * PHPC-390: Fix OnUpdateString calls within OnUpdateDebug 2015-11-07 Jeremy Mikola * PHPC-373: Additional MAKE_STD_ZVAL() cleanup 2015-11-07 Jeremy Mikola * PHPC-374: zend_string updates for OnUpdateDebug 2015-11-07 Jeremy Mikola * PHPC-404: Additional hash API changes 2015-11-07 Jeremy Mikola * PHPC-370: Additionally return_value_ptr and return_value_used suppressions 2015-11-07 Jeremy Mikola * PHPC-369: Additional Z__OBJ_P() macros 2015-11-07 Jeremy Mikola * PHPC-399: Additional zval_used_for_init cleanup 2015-09-24 Hannes Magnusson * PHPC-431: Add the testcase from the report 2015-09-24 Hannes Magnusson * PHPC-431: Segfault when using Manager through singleton class 2015-09-02 Hannes Magnusson * Use ZVAL_COPY_VALUE() 2015-09-01 Hannes Magnusson * Enable PHP7 on Travis 2015-09-01 Hannes Magnusson * PHPC-391 & PHPC-389: Stream and SSL API changes 2015-09-01 Hannes Magnusson * PHPC-387: Properly init the iterator, and don't free it on dtor 2015-09-01 Hannes Magnusson * _id doesn't have to be object 2015-09-01 Hannes Magnusson * Fix incorrect version checks 2015-09-01 Hannes Magnusson * PHPC-405: zval drop a level; zval*->zval, zval**->zval* 2015-09-01 Hannes Magnusson * PHPC-404: off-by-one hash api changes 2015-09-01 Hannes Magnusson * PHPC-390: php.ini updates 2015-08-31 Hannes Magnusson * littlebit to eager on the zend_string, this is PHP5 2015-08-31 Hannes Magnusson * Get the zend_string value 2015-08-31 Hannes Magnusson * hash API changes, off-by-ones 2015-08-31 Hannes Magnusson * PHPC-380: Use the compatability macros to get the object 2015-08-31 Hannes Magnusson * Properly initialize the zval* we are working with 2015-08-31 Hannes Magnusson * +1 in PHP5, not PHP7 2015-08-31 Hannes Magnusson * Include numeric keys as well 2015-09-01 Patrick Boyd * Object property names missing due to lack of key length 2015-08-31 Hannes Magnusson * Should all compile now! 2015-08-31 Hannes Magnusson * Simpilfy iterating over a zval 2015-08-31 Hannes Magnusson * Use Z_ISUNDEF() to check the zval 2015-08-31 Hannes Magnusson * WS 2015-08-31 Patrick Boyd * PHPC-400: Handle IS_TRUE and IS_FALSE 2015-08-31 Hannes Magnusson * Simplify IS_ARRAY/IS_OBJECT discovery for PHP7 2015-08-31 Hannes Magnusson * PHPC-373: MAKE_STD_ZVAL() and zval* -> zval upgrades 2015-08-31 Hannes Magnusson * We already know the length 2015-08-31 Patrick Boyd * str_efree() not defined in PHP7 2015-08-31 Hannes Magnusson * PHPC-397: RETURN_*() should RETURN ! :) 2015-08-31 Hannes Magnusson * PHPC-399: zval_used_for_init is no longer needed (or defined) 2015-08-31 Hannes Magnusson * PHPC-398: zend_parse_parameter 's' expects a char* and size_t now 2015-08-28 Patrick Boyd * PHP7 upgrades 2015-08-31 Hannes Magnusson * PHPC-373: MAKE_STD_ZVAL() is gone 2015-08-31 Hannes Magnusson * PHPC-397: RETURN_STRING() duplicate argument removed 2015-08-31 Hannes Magnusson * PHPC-387: get_current_data() API changes 2015-08-31 Hannes Magnusson * PHPC-397: dup argument in most string macros removed 2015-08-31 Patrick Boyd * PHPC-380: Use our bc type for free_object argument 2015-08-31 Hannes Magnusson * PHPC-397: dup argument in most string macros removed 2015-08-31 Patrick Boyd * PHPC-396: HashTable no longer contains nApplyCount 2015-08-27 Patrick Boyd * PHPC-394: Fix issue with WriteException and zend_read_property 2015-08-31 Hannes Magnusson * PHPC-380: PHP7 create/free object changes 2015-08-27 Patrick Boyd * PHPC-380: create/free object handlers for PHP7 2015-08-27 Hannes Magnusson * Define the TODOs for PHP5, these are PHP7 TODOs 2015-08-27 Hannes Magnusson * PHPC-385: Remove leftover braces 2015-08-27 Hannes Magnusson * Sprinkle TODOs -- it compiles now! 2015-08-27 Hannes Magnusson * PHPC-374: php_stream_xport_create() now wants zend_string 2015-08-27 Hannes Magnusson * PHPC-388 - dtor on bson_to_zval() failure 2015-08-27 Hannes Magnusson * PHPC-387: Iterator API changes 2015-08-27 Hannes Magnusson * PHPC-386: Forward port Z_PHPDATE_P() to get php_date_obj 2015-08-27 Hannes Magnusson * PHPC-385: add_assoc_string_ex() doesn't have a duplicate param in PHP7 2015-08-27 Hannes Magnusson * PHPC-384: php_stream's no longer have resource ids 2015-08-27 Hannes Magnusson * PHPC-383: Simplify getting the current exception zval* 2015-08-26 Hannes Magnusson * PHPC-376: Cursor var_dump() is weird 2015-08-25 Hannes Magnusson * PHPC-373: Remove MAKE_STD_ZVAL() usage 2015-08-25 Hannes Magnusson * PHPC-374: zend_string* vs char* PHP API changes (1/many) 2015-08-25 Hannes Magnusson * PHPC-375: TSRMLS_FETCH_FROM_CTX() not applicable in PHP7 2015-08-25 Hannes Magnusson * PHPC-372: zend_throw_exception() return value changes 2015-08-25 Hannes Magnusson * PHP7: Start a phongo_compat.c with things that shouldn't be done in headers 2015-08-25 Hannes Magnusson * PHP7: Lets start with just php_phongo.c for now 2015-08-24 Hannes Magnusson * PHPC-371: Prep for PHP7 resource changes 2015-08-24 Hannes Magnusson * PHPC-370: Hardcode return_value_used to 1 in PHP7 2015-08-24 Hannes Magnusson * PHPC-370: return_value_ptr and return_value_used removed in PHP7 2015-08-24 Hannes Magnusson * PHPC-369: Use the new Z__OBJ_P() macros 2015-08-24 Hannes Magnusson * PHPC-369: Split PHP5 and PHP7 style custom object struct declrations 2015-08-24 Hannes Magnusson * PHPC-368: Refactor MongoDB\Driver\Manager ctor 2015-08-24 Hannes Magnusson * Fix const casting warning in php_array_api 2015-08-24 Hannes Magnusson * Resync with GitHub: https://github.com/sgolemon/php-array-api 2015-12-15 Jeremy Mikola * Back to -dev 2015-12-15 Jeremy Mikola * Include libbson and libmongoc version files in PECL package 2015-12-15 Jeremy Mikola * Add 1.1.0 release notes RELEASE 1.1.0 ------------- 2015-12-15 Jeremy Mikola * Initial release notes for 1.1 series 2015-12-15 Jeremy Mikola * Bump extension version to 1.1.0 2015-12-14 Jeremy Mikola * PHPC-509: Default Manager URI to "mongodb://localhost:27017/" 2015-12-14 Jeremy Mikola * PHPC-448: Fix arginfo for ReadConcern constructor 2015-12-12 Jorgen Evens * PHPC-514: Fix --with-mongodb-sasl flag 2015-12-14 Hannes Magnusson * PHPC-512: Disable async stream connections 2015-12-14 Jeremy Mikola * PHPC-508: Construct valid stream URI for IPv6 literals 2015-12-10 Jeremy Mikola * PHPC-448: Manager::getReadConcern() and URI test 2015-12-10 Jeremy Mikola * PHPC-448: Support readConcern option on Query 2015-12-10 Jeremy Mikola * PHPC-448: Implement ReadConcern class 2015-12-10 Jeremy Mikola * Fix include for mongoc-write-concern-private.h 2015-12-11 Hannes Magnusson * Fix package license to be consistent with the source files 2015-12-11 Hannes Magnusson * Accept MongoDB 3.2 package repo public keys on test VM 2015-12-05 Jeremy Mikola * PHPC-443: Support "bypassDocumentValidation" option in BulkWrite 2015-12-10 Jeremy Mikola * Update package repo public key for Travis CI builds 2015-12-10 Jeremy Mikola * Define STANDALONE as MongoDB 3.2 on Travis CI 2015-12-09 Jeremy Mikola * Bump libmongoc for CDRIVER-1046 memory leak fix 2015-12-09 Jeremy Mikola * PHPC-450: failReceivedGetmore does not support getMore commands 2015-12-09 Jeremy Mikola * PHPC-450: Don't assert exact isMaster response when dumping Servers 2015-12-09 Jeremy Mikola * PHPC-450: Split query tests for OP_QUERY and find command 2015-12-09 Jeremy Mikola * Add MongoDB 3.0 replica set test environment 2015-12-09 Jeremy Mikola * PHPC-450: Profiled aggregate commands log the collection NS in 3.2 2015-12-08 Jeremy Mikola * PHPC-450: Update open cursor check for MongoDB 3.2 2015-12-10 Derick Rethans * Use more descriptive unused value 2015-12-07 Hannes Magnusson * Fixed PHPC-502: bson_init_static(): precondition failed: data 2015-12-09 Jeremy Mikola * Use consistent name for MongoDB 3.0 test server 2015-12-08 Jeremy Mikola * PHPC-450: Enable majority read concern by default in MO 2015-12-08 Jeremy Mikola * PHPC-450: Use MongoDB 3.2 final for testing 2015-12-08 Jeremy Mikola * Make server startup via MO more robust 2015-12-08 Jeremy Mikola * Register STANDALONE-3.0 with the test suite 2015-12-08 Jeremy Mikola * STANDALONE-3.0 port conflicted with STANDALONE-2.4 2015-12-08 Derick Rethans * Bump libmongoc and libbson to 1.3.0 releases 2015-12-02 Derick Rethans * This code has changed in 3.2, and make the error message clear 2015-12-02 Derick Rethans * Added 3.2.0rc5 to our Mongo Orchestration suite 2015-12-02 Derick Rethans * Added some more phpt test leftovers to .gitignore 2015-12-08 Remi Collet * libmongoc 1.3 is not compatible 2015-12-07 Jeremy Mikola * Revise prep-release.php handling 2015-12-07 Jeremy Mikola * Back to -dev 2015-12-07 Jeremy Mikola * Add 1.0.1 release notes mongodb-1.1.5/RELEASE-1.1.50000664000175000017500000000044012673034026014447 0ustar jmikolajmikolaRELEASE 1.1.5 ------------- 2016-03-18 Jeremy Mikola * PHPC-632: Define MONGOC_NO_AUTOMATIC_GLOBALS when bundling libmongoc 2016-03-10 Jeremy Mikola * Back to -dev 2016-03-10 Jeremy Mikola * Add 1.1.4 release notes mongodb-1.1.5/Vagrantfile0000664000175000017500000000747412673034026015207 0ustar jmikolajmikola# -*- mode: ruby -*- # vi: set ft=ruby et sw=2 : Vagrant.configure(2) do |config| config.vm.synced_folder ".", "/phongo" config.vm.provider "vmware_workstation" do |vmware, override| vmware.vmx["memsize"] = "8192" vmware.vmx["numvcpus"] = "2" end config.vm.define "mo", primary: true do |mo| mo.vm.network "private_network", ip: "192.168.112.10" mo.vm.box = "http://files.vagrantup.com/precise64.box" mo.vm.provider "vmware_workstation" do |vmware, override| override.vm.box_url = 'http://files.vagrantup.com/precise64_vmware.box' override.vm.provision "shell", path: "scripts/vmware/kernel.sh", privileged: true end mo.vm.provision "shell", path: "scripts/ubuntu/essentials.sh", privileged: true mo.vm.provision "file", source: "scripts/ubuntu/mongo-orchestration-config.json", destination: "mongo-orchestration-config.json" mo.vm.provision "shell", path: "scripts/ubuntu/mongo-orchestration.sh", privileged: true mo.vm.provision "shell", path: "scripts/ubuntu/ldap/install.sh", privileged: true end config.vm.define "ldap", autostart: false do |ldap| ldap.vm.network "private_network", ip: "192.168.112.20" ldap.vm.box = "http://puppet-vagrant-boxes.puppetlabs.com/centos-64-x64-vbox4210-nocm.box" ldap.vm.provider "vmware_workstation" do |vmware, override| override.vm.box_url = "https://dl.dropbox.com/u/5721940/vagrant-boxes/vagrant-centos-6.4-x86_64-vmware_fusion.box" override.vm.provision "shell", path: "scripts/vmware/kernel.sh", privileged: true end ldap.vm.provision "shell", path: "scripts/centos/essentials.sh", privileged: true ldap.vm.provision "shell", path: "scripts/centos/ldap/install.sh", privileged: true end config.vm.define "freebsd", autostart: false do |bsd| bsd.vm.network "private_network", ip: "192.168.112.30" bsd.vm.box = "geoffgarside/freebsd-10.0" bsd.vm.provision "shell", path: "scripts/freebsd/essentials.sh", privileged: true bsd.vm.provision "file", source: "/tmp/PHONGO-SERVERS.json", destination: "/tmp/PHONGO-SERVERS.json" bsd.vm.provision "file", source: "scripts/configs/.gdbinit", destination: "/home/vagrant/.gdbinit" bsd.vm.provision "shell", path: "scripts/freebsd/phongo.sh", privileged: true bsd.vm.synced_folder ".", "/phongo", :nfs => true, id: "vagrant-root" end config.vm.define "precise64" do |linux| linux.vm.network "private_network", ip: "192.168.112.40" linux.vm.box = "http://files.vagrantup.com/precise64.box" linux.vm.provider "vmware_workstation" do |vmware, override| override.vm.box_url = 'http://files.vagrantup.com/precise64_vmware.box' override.vm.provision "shell", path: "scripts/vmware/kernel.sh", privileged: true end linux.vm.provision "shell", path: "scripts/ubuntu/essentials.sh", privileged: true linux.vm.provision "file", source: "/tmp/PHONGO-SERVERS.json", destination: "/tmp/PHONGO-SERVERS.json" linux.vm.provision "file", source: "scripts/configs/.gdbinit", destination: "/home/vagrant/.gdbinit" linux.vm.provision "shell", path: "scripts/ubuntu/phongo.sh", privileged: true end config.vm.define "precise32" do |linux| linux.vm.network "private_network", ip: "192.168.112.50" linux.vm.box = "bjori/precise32" linux.vm.provider "vmware_workstation" do |vmware, override| override.vm.box_url = "bjori/precise32" override.vm.provision "shell", path: "scripts/vmware/kernel.sh", privileged: true end linux.vm.provision "shell", path: "scripts/ubuntu/essentials.sh", privileged: true linux.vm.provision "file", source: "/tmp/PHONGO-SERVERS.json", destination: "/tmp/PHONGO-SERVERS.json" linux.vm.provision "file", source: "scripts/configs/.gdbinit", destination: "/home/vagrant/.gdbinit" linux.vm.provision "shell", path: "scripts/ubuntu/phongo.sh", privileged: true end end mongodb-1.1.5/config.m40000664000175000017500000005067012673034026014525 0ustar jmikolajmikoladnl config.m4 for extension mongodb PHP_ARG_ENABLE(mongodb, whether to enable mongodb support, [ --enable-mongodb Enable mongodb support]) PHP_ARG_WITH(openssl-dir, OpenSSL dir for mongodb, [ --with-openssl-dir[=DIR] openssl install prefix], yes, no) dnl borrowed from PHP acinclude.m4 AC_DEFUN([PHP_BSON_BIGENDIAN], [AC_CACHE_CHECK([whether byte ordering is bigendian], ac_cv_c_bigendian_php, [ ac_cv_c_bigendian_php=unknown AC_TRY_RUN( [ int main(void) { short one = 1; char *cp = (char *)&one; if (*cp == 0) { return(0); } else { return(1); } } ], [ac_cv_c_bigendian_php=yes], [ac_cv_c_bigendian_php=no], [ac_cv_c_bigendian_php=unknown]) ]) if test $ac_cv_c_bigendian_php = yes; then BSON_BYTE_ORDER=4321 else BSON_BYTE_ORDER=1234 fi AC_SUBST(BSON_BYTE_ORDER) ]) dnl Borrowed from sapi/fpm/config.m4 AC_DEFUN([PHP_BSON_CLOCK], [ have_clock_gettime=no AC_MSG_CHECKING([for clock_gettime]) AC_TRY_LINK([ #include ], [struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts);], [ have_clock_gettime=yes AC_MSG_RESULT([yes]) ], [ AC_MSG_RESULT([no]) ]) if test "$have_clock_gettime" = "no"; then AC_MSG_CHECKING([for clock_gettime in -lrt]) SAVED_LIBS="$LIBS" LIBS="$LIBS -lrt" AC_TRY_LINK([ #include ], [struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts);], [ have_clock_gettime=yes AC_MSG_RESULT([yes]) ], [ LIBS="$SAVED_LIBS" AC_MSG_RESULT([no]) ]) fi if test "$have_clock_gettime" = "yes"; then BSON_HAVE_CLOCK_GETTIME=1 AC_SUBST(BSON_HAVE_CLOCK_GETTIME) fi ]) MONGOC_SYMBOL_SUFFIX="priv" AC_MSG_CHECKING(PHP version) PHP_FOUND_VERSION=`${PHP_CONFIG} --version` PHP_FOUND_VERNUM=`echo "${PHP_FOUND_VERSION}" | $AWK 'BEGIN { FS = "."; } { printf "%d", ([$]1 * 100 + [$]2) * 100 + [$]3;}'` AC_MSG_RESULT($PHP_FOUND_VERNUM) if test "$MONGODB" != "no"; then PHP_ARG_ENABLE(developer-flags, whether to enable developer build flags, [ --enable-developer-flags Enable developer flags],, no) if test "$PHP_DEVELOPER_FLAGS" = "yes"; then dnl Warn about functions which might be candidates for format attributes PHP_CHECK_GCC_ARG(-Wmissing-format-attribute, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wmissing-format-attribute") dnl Avoid duplicating values for an enum PHP_CHECK_GCC_ARG(-Wduplicate-enum, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wduplicate-enum") dnl Warns on mismatches between #ifndef and #define header guards PHP_CHECK_GCC_ARG(-Wheader-guard, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wheader-guard") dnl logical not of a non-boolean expression PHP_CHECK_GCC_ARG(-Wlogical-not-parentheses, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wlogical-not-parentheses") dnl Warn about suspicious uses of logical operators in expressions PHP_CHECK_GCC_ARG(-Wlogical-op, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wlogical-op") dnl memory error detector. dnl FIXME: -fsanitize=address,undefined for clang. The PHP_CHECK_GCC_ARG macro isn't happy about that string :( PHP_CHECK_GCC_ARG(-fsanitize-address, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -fsanitize-address") dnl Enable frame debugging PHP_CHECK_GCC_ARG(-fno-omit-frame-pointer, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -fno-omit-frame-pointer") dnl Make sure we don't optimize calls PHP_CHECK_GCC_ARG(-fno-optimize-sibling-calls, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -fno-optimize-sibling-calls") PHP_CHECK_GCC_ARG(-Wlogical-op-parentheses, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wlogical-op-parentheses") PHP_CHECK_GCC_ARG(-Wbool-conversion, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wbool-conversion") PHP_CHECK_GCC_ARG(-Wloop-analysis, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wloop-analysis") PHP_CHECK_GCC_ARG(-Wsizeof-array-argument, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wsizeof-array-argument") PHP_CHECK_GCC_ARG(-Wstring-conversion, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wstring-conversion") PHP_CHECK_GCC_ARG(-Wno-variadic-macros, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wno-variadic-macros") PHP_CHECK_GCC_ARG(-Wno-sign-compare, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wno-sign-compare") PHP_CHECK_GCC_ARG(-fstack-protector, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -fstack-protector") PHP_CHECK_GCC_ARG(-fno-exceptions, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -fno-exceptions") PHP_CHECK_GCC_ARG(-Wformat-security, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wformat-security") PHP_CHECK_GCC_ARG(-Wformat-nonliteral, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wformat-nonliteral") PHP_CHECK_GCC_ARG(-Winit-self, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Winit-self") PHP_CHECK_GCC_ARG(-Wwrite-strings, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wwrite-strings") PHP_CHECK_GCC_ARG(-Wenum-compare, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wenum-compare") PHP_CHECK_GCC_ARG(-Wempty-body, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wempty-body") PHP_CHECK_GCC_ARG(-Wparentheses, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wparentheses") PHP_CHECK_GCC_ARG(-Wdeclaration-after-statement, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Wdeclaration-after-statement") if test "$PHP_FOUND_VERNUM" -ge "50400"; then PHP_CHECK_GCC_ARG(-Werror, _MAINTAINER_CFLAGS="$_MAINTAINER_CFLAGS -Werror") fi MAINTAINER_CFLAGS="-Wextra $_MAINTAINER_CFLAGS -Wno-unused-parameter -Wno-unused-but-set-variable -Wno-missing-field-initializers" STD_CFLAGS="-g -O0 -Wall" dnl EXTRA_LDFLAGS="-Wl,--no-undefined" fi PHP_ARG_ENABLE(coverage, whether to enable code coverage, [ --enable-coverage Enable developer code coverage information],, no) if test "$PHP_COVERAGE" = "yes"; then PHP_CHECK_GCC_ARG(-fprofile-arcs, COVERAGE_CFLAGS="$COVERAGE_CFLAGS -fprofile-arcs") PHP_CHECK_GCC_ARG(-ftest-coverage, COVERAGE_CFLAGS="$COVERAGE_CFLAGS -ftest-coverage") EXTRA_LDFLAGS="$COVERAGE_CFLAGS" fi MONGODB_BSON="\ src/bson.c \ "; MONGODB_BSON_CLASSES="\ src/BSON/Type.c \ src/BSON/Unserializable.c \ src/BSON/Serializable.c \ src/BSON/Persistable.c \ src/BSON/Binary.c \ src/BSON/Javascript.c \ src/BSON/MaxKey.c \ src/BSON/MinKey.c \ src/BSON/ObjectID.c \ src/BSON/Regex.c \ src/BSON/Timestamp.c \ src/BSON/UTCDateTime.c \ "; MONGODB_ROOT="\ php_phongo.c \ phongo_compat.c \ "; MONGODB_CONTRIB="\ src/contrib/php-ssl.c \ "; MONGODB_MONGODB_CLASSES="\ src/MongoDB/Command.c \ src/MongoDB/Cursor.c \ src/MongoDB/CursorId.c \ src/MongoDB/Manager.c \ src/MongoDB/Query.c \ src/MongoDB/ReadConcern.c \ src/MongoDB/ReadPreference.c \ src/MongoDB/Server.c \ src/MongoDB/BulkWrite.c \ src/MongoDB/WriteConcern.c \ src/MongoDB/WriteConcernError.c \ src/MongoDB/WriteError.c \ src/MongoDB/WriteResult.c \ "; MONGODB_MONGODB_EXCEPTIONS="\ src/MongoDB/Exception/Exception.c \ src/MongoDB/Exception/LogicException.c \ src/MongoDB/Exception/RuntimeException.c \ src/MongoDB/Exception/UnexpectedValueException.c \ src/MongoDB/Exception/InvalidArgumentException.c \ src/MongoDB/Exception/ConnectionException.c \ src/MongoDB/Exception/AuthenticationException.c \ src/MongoDB/Exception/SSLConnectionException.c \ src/MongoDB/Exception/ExecutionTimeoutException.c \ src/MongoDB/Exception/ConnectionTimeoutException.c \ src/MongoDB/Exception/WriteException.c \ src/MongoDB/Exception/BulkWriteException.c \ "; YAJL_SOURCES="\ yajl_version.c \ yajl.c \ yajl_encode.c \ yajl_lex.c \ yajl_parser.c \ yajl_buf.c \ yajl_tree.c \ yajl_alloc.c \ yajl_gen.c "; BSON_SOURCES="\ bcon.c \ bson.c \ bson-atomic.c \ bson-clock.c \ bson-context.c \ bson-error.c \ bson-iter.c \ bson-iso8601.c \ bson-json.c \ bson-keys.c \ bson-md5.c \ bson-memory.c \ bson-oid.c \ bson-reader.c \ bson-string.c \ bson-timegm.c \ bson-utf8.c \ bson-value.c \ bson-version-functions.c \ bson-writer.c "; MONGOC_SOURCES="\ mongoc-array.c \ mongoc-async.c \ mongoc-async-cmd.c \ mongoc-buffer.c \ mongoc-bulk-operation.c \ mongoc-b64.c \ mongoc-client.c \ mongoc-client-pool.c \ mongoc-cluster.c \ mongoc-collection.c \ mongoc-counters.c \ mongoc-cursor.c \ mongoc-cursor-array.c \ mongoc-cursor-transform.c \ mongoc-cursor-cursorid.c \ mongoc-database.c \ mongoc-find-and-modify.c \ mongoc-init.c \ mongoc-gridfs.c \ mongoc-gridfs-file.c \ mongoc-gridfs-file-page.c \ mongoc-gridfs-file-list.c \ mongoc-host-list.c \ mongoc-index.c \ mongoc-list.c \ mongoc-log.c \ mongoc-matcher-op.c \ mongoc-matcher.c \ mongoc-memcmp.c \ mongoc-opcode.c \ mongoc-queue.c \ mongoc-read-concern.c \ mongoc-read-prefs.c \ mongoc-rpc.c \ mongoc-set.c \ mongoc-server-description.c \ mongoc-server-stream.c \ mongoc-socket.c \ mongoc-stream.c \ mongoc-stream-buffered.c \ mongoc-stream-file.c \ mongoc-stream-gridfs.c \ mongoc-stream-socket.c \ mongoc-topology.c \ mongoc-topology-scanner.c \ mongoc-topology-description.c \ mongoc-uri.c \ mongoc-util.c \ mongoc-version-functions.c \ mongoc-write-command.c \ mongoc-write-concern.c "; MONGOC_SOURCES_SSL="\ mongoc-rand.c \ mongoc-scram.c \ mongoc-stream-tls.c \ mongoc-ssl.c "; MONGOC_SOURCES_SASL=mongoc-sasl.c if test "$ext_shared" = "no"; then PHP_ADD_SOURCES(PHP_EXT_DIR(mongodb), $MONGODB_BSON) PHP_ADD_SOURCES(PHP_EXT_DIR(mongodb), $MONGODB_BSON_CLASSES) PHP_ADD_SOURCES(PHP_EXT_DIR(mongodb), $MONGODB_MONGODB_CLASSES) PHP_ADD_SOURCES(PHP_EXT_DIR(mongodb), $MONGODB_MONGODB_EXCEPTIONS) PHP_ADD_SOURCES(PHP_EXT_DIR(mongodb), $MONGODB_CONTRIB) else PHP_ADD_SOURCES_X(PHP_EXT_DIR(mongodb), $MONGODB_BSON, [$STD_CFLAGS $MAINTAINER_CFLAGS $COVERAGE_CFLAGS], shared_objects_mongodb, yes) PHP_ADD_SOURCES_X(PHP_EXT_DIR(mongodb), $MONGODB_BSON_CLASSES, [$STD_CFLAGS $MAINTAINER_CFLAGS $COVERAGE_CFLAGS], shared_objects_mongodb, yes) PHP_ADD_SOURCES_X(PHP_EXT_DIR(mongodb), $MONGODB_MONGODB_CLASSES, [$STD_CFLAGS $MAINTAINER_CFLAGS $COVERAGE_CFLAGS], shared_objects_mongodb, yes) PHP_ADD_SOURCES_X(PHP_EXT_DIR(mongodb), $MONGODB_MONGODB_EXCEPTIONS, [$STD_CFLAGS $MAINTAINER_CFLAGS $COVERAGE_CFLAGS], shared_objects_mongodb, yes) PHP_ADD_SOURCES_X(PHP_EXT_DIR(mongodb), $MONGODB_CONTRIB, [$STD_CFLAGS $MAINTAINER_CFLAGS $COVERAGE_CFLAGS], shared_objects_mongodb, yes) fi PHP_ARG_WITH(libbson, whether to use system libbson, [ --with-libbson Use system libbson], no, no) if test "$PHP_LIBBSON" != "no"; then AC_PATH_PROG(PKG_CONFIG, pkg-config, no) AC_MSG_CHECKING(for libbson) if test -x "$PKG_CONFIG" && $PKG_CONFIG --exists libbson-1.0; then if $PKG_CONFIG libbson-1.0 --atleast-version 1.3.3; then LIBBSON_INC=`$PKG_CONFIG libbson-1.0 --cflags` LIBBSON_LIB=`$PKG_CONFIG libbson-1.0 --libs` LIBBSON_VER=`$PKG_CONFIG libbson-1.0 --modversion` AC_MSG_RESULT(version $LIBBSON_VER found) else AC_MSG_ERROR(system libbson must be upgraded to version >= 1.3.3) fi else AC_MSG_ERROR(pkgconfig and libbson must be installed) fi PHP_EVAL_INCLINE($LIBBSON_INC) PHP_EVAL_LIBLINE($LIBBSON_LIB, MONGODB_SHARED_LIBADD) AC_DEFINE(HAVE_SYSTEM_LIBBSON, 1, [Use system libbson]) else PHP_ADD_SOURCES_X(PHP_EXT_DIR(mongodb)[src/libbson/src/yajl], $YAJL_SOURCES, [$STD_CFLAGS], shared_objects_mongodb, yes) PHP_ADD_SOURCES_X(PHP_EXT_DIR(mongodb)[src/libbson/src/bson], $BSON_SOURCES, [$STD_CFLAGS], shared_objects_mongodb, yes) fi dnl libmongoc stuff {{{ AC_MSG_CHECKING(configuring libmongoc) AC_MSG_RESULT(...) PHP_ARG_WITH(libmongoc, whether to use system libmongoc, [ --with-libmongoc Use system libmongoc], no, no) AC_DEFINE(HAVE_MONGOC, 1, [Kinda useless extension without it..]) if test "$PHP_LIBMONGOC" != "no"; then AC_PATH_PROG(PKG_CONFIG, pkg-config, no) AC_MSG_CHECKING(for libmongoc) if test -x "$PKG_CONFIG" && $PKG_CONFIG --exists libmongoc-1.0 && $PKG_CONFIG --exists libmongoc-priv; then if $PKG_CONFIG libmongoc-1.0 --atleast-version 1.3.3; then LIBMONGOC_INC=`$PKG_CONFIG libmongoc-priv --cflags` LIBMONGOC_LIB=`$PKG_CONFIG libmongoc-priv --libs` LIBMONGOC_VER=`$PKG_CONFIG libmongoc-priv --modversion` AC_MSG_RESULT(version $LIBMONGOC_VER found) CFLAGS="$CFLAGS -DMONGOC_I_AM_A_DRIVER" else AC_MSG_ERROR(system libmongoc must be upgraded to version >= 1.3.3) fi else AC_MSG_ERROR(pkgconfig and mongoc must be installed) fi PHP_EVAL_INCLINE($LIBMONGOC_INC) PHP_EVAL_LIBLINE($LIBMONGOC_LIB, MONGODB_SHARED_LIBADD) AC_DEFINE(HAVE_SYSTEM_LIBMONGOC, 1, [Use system libmongoc]) else CPPFLAGS="$CPPFLAGS -DBSON_COMPILATION -DMONGOC_COMPILATION -DMONGOC_TRACE -DMONGOC_NO_AUTOMATIC_GLOBALS" PHP_ADD_SOURCES_X(PHP_EXT_DIR(mongodb)[src/libmongoc/src/mongoc], $MONGOC_SOURCES, [$STD_CFLAGS], shared_objects_mongodb, yes) PHP_ADD_SOURCES_X(PHP_EXT_DIR(mongodb)[src/libmongoc/src/mongoc], $MONGOC_SOURCES_SSL, [$STD_CFLAGS], shared_objects_mongodb, yes) PHP_ADD_SOURCES_X(PHP_EXT_DIR(mongodb)[src/libmongoc/src/mongoc], $MONGOC_SOURCES_SASL, [$STD_CFLAGS], shared_objects_mongodb, yes) PHP_SETUP_OPENSSL(MONGODB_SHARED_LIBADD) MONGOC_ENABLE_SSL=1 AC_SUBST(MONGOC_ENABLE_SSL) fi PHP_ARG_WITH(pcre-dir, for pcre-dir install prefix, [ --with-pcre-dir[=DIR] mongodb: pcre install prefix], auto, yes) if test "$PHP_PCRE_DIR" != "no"; then AC_MSG_CHECKING(for pcre) for i in $PHP_PCRE_DIR /usr /usr/local; do if test -f $i/include/pcre.h; then MONGODB_PCRE_DIR=$i/include AC_MSG_RESULT(found in $i) break fi done if test -z "$MONGODB_PCRE_DIR"; then AC_MSG_RESULT(not found) else PHP_ADD_INCLUDE($MONGODB_PCRE_DIR) fi fi PHP_ARG_WITH(mongodb-sasl, for Cyrus SASL support, [ --with-mongodb-sasl[=DIR] mongodb: Include Cyrus SASL support], auto, no) if test "$PHP_MONGODB_SASL" != "no"; then AC_MSG_CHECKING(for SASL) for i in $PHP_MONGODB_SASL /usr /usr/local; do if test -f $i/include/sasl/sasl.h; then MONGODB_SASL_DIR=$i AC_MSG_RESULT(found in $i) break fi done if test -z "$MONGODB_SASL_DIR"; then AC_MSG_RESULT(not found) if test "$PHP_MONGODB_SASL" != "auto"; then AC_MSG_ERROR([sasl.h not found!]) else AC_SUBST(MONGOC_ENABLE_SASL, 0) AC_SUBST(MONGOC_HAVE_SASL_CLIENT_DONE, 0) fi else PHP_CHECK_LIBRARY(sasl2, sasl_version, [ PHP_ADD_INCLUDE($MONGODB_SASL_DIR) PHP_ADD_LIBRARY_WITH_PATH(sasl2, $MONGODB_SASL_DIR/$PHP_LIBDIR, MONGODB_SHARED_LIBADD) MONGOC_ENABLE_SASL=1 AC_SUBST(MONGOC_ENABLE_SASL) ], [ if test "$MONGODB_SASL" != "auto"; then AC_MSG_ERROR([MONGO SASL check failed. Please check config.log for more information.]) fi ], [ -L$MONGODB_SASL_DIR/$PHP_LIBDIR ]) PHP_CHECK_LIBRARY(sasl2, sasl_client_done, [ AC_SUBST(MONGOC_HAVE_SASL_CLIENT_DONE, 1) ], [ AC_SUBST(MONGOC_HAVE_SASL_CLIENT_DONE, 0) ]) fi else AC_SUBST(MONGOC_ENABLE_SASL, 0) AC_SUBST(MONGOC_HAVE_SASL_CLIENT_DONE, 0) fi m4_include(src/libmongoc/build/autotools/WeakSymbols.m4) m4_include(src/libmongoc/build/autotools/m4/ax_pthread.m4) AX_PTHREAD AC_CHECK_FUNCS([shm_open], [SHM_LIB=], [AC_CHECK_LIB([rt], [shm_open], [SHM_LIB=-lrt], [SHM_LIB=])]) MONGODB_SHARED_LIBADD="$MONGODB_SHARED_LIBADD $SHM_LIB" dnl PHP_ADD_LIBRARY_WITH_PATH(bson-1.0, src/libbson/.libs, MONGODB_SHARED_LIBADD) dnl PHP_ADD_LIBRARY_WITH_PATH(mongoc-priv, src/libmongoc/.libs, MONGODB_SHARED_LIBADD) EXTRA_CFLAGS="$PTHREAD_CFLAGS $SASL_CFLAGS" PHP_SUBST(EXTRA_CFLAGS) PHP_SUBST(EXTRA_LDFLAGS) MONGODB_SHARED_LIBADD="$MONGODB_SHARED_LIBADD $PTHREAD_LIBS $SASL_LIBS" PHP_SUBST(MONGODB_SHARED_LIBADD) dnl }}} PHP_NEW_EXTENSION(mongodb, $MONGODB_ROOT, $ext_shared,, [$STD_CFLAGS $MAINTAINER_CFLAGS $COVERAGE_CFLAGS]) PHP_ADD_EXTENSION_DEP(mongodb, spl) PHP_ADD_INCLUDE([$ext_srcdir/src/BSON/]) PHP_ADD_INCLUDE([$ext_srcdir/src/MongoDB/]) PHP_ADD_INCLUDE([$ext_srcdir/src/MongoDB/Exception/]) PHP_ADD_INCLUDE([$ext_srcdir/src/contrib/]) PHP_ADD_BUILD_DIR([$ext_builddir/src/BSON/]) PHP_ADD_BUILD_DIR([$ext_builddir/src/MongoDB/]) PHP_ADD_BUILD_DIR([$ext_builddir/src/MongoDB/Exception/]) PHP_ADD_BUILD_DIR([$ext_builddir/src/contrib/]) if test "$PHP_LIBMONGOC" == "no"; then PHP_ADD_INCLUDE([$ext_srcdir/src/libmongoc/src/mongoc/]) PHP_ADD_BUILD_DIR([$ext_builddir/src/libmongoc/src/mongoc/]) fi if test "$PHP_LIBBSON" == "no"; then m4_include(src/libbson/build/autotools/CheckAtomics.m4) m4_include(src/libbson/build/autotools/FindDependencies.m4) m4_include(src/libbson/build/autotools/m4/ac_compile_check_sizeof.m4) m4_include(src/libbson/build/autotools/m4/ac_create_stdint_h.m4) AC_CREATE_STDINT_H([$srcdir/src/libbson/src/bson/bson-stdint.h]) PHP_ADD_INCLUDE([$ext_srcdir/src/libbson/src/]) PHP_ADD_INCLUDE([$ext_srcdir/src/libbson/src/yajl/]) PHP_ADD_INCLUDE([$ext_srcdir/src/libbson/src/bson/]) PHP_ADD_BUILD_DIR([$ext_builddir/src/libbson/src/]) PHP_ADD_BUILD_DIR([$ext_builddir/src/libbson/src/yajl/]) PHP_ADD_BUILD_DIR([$ext_builddir/src/libbson/src/bson/]) fi dnl MONGODB_SHARED_DEPENDENCIES="mongodbdep" dnl PHP_SUBST(MONGODB_SHARED_DEPENDENCIES) PHP_BSON_BIGENDIAN AC_HEADER_STDBOOL BSON_EXTRA_ALIGN=0 AC_SUBST(BSON_EXTRA_ALIGN) if test "$ac_cv_header_stdbool_h" = "yes"; then BSON_HAVE_STDBOOL_H=1 else BSON_HAVE_STDBOOL_H=0 fi AC_SUBST(BSON_HAVE_STDBOOL_H) BSON_OS=1 AC_SUBST(BSON_OS) PHP_BSON_CLOCK AC_CHECK_FUNC(strnlen,ac_cv_func_strnlen=yes,ac_cv_func_strnlen=no) if test "$ac_cv_func_strnlen" = "yes"; then BSON_HAVE_STRNLEN=1 fi AC_SUBST(BSON_HAVE_STRNLEN) AC_CHECK_FUNC(snprintf,ac_cv_func_snprintf=yes,ac_cv_func_snprintf=no) if test "$ac_cv_func_snprintf" = "yes"; then BSON_HAVE_SNPRINTF=1 fi AC_SUBST(BSON_HAVE_SNPRINTF) if test "$PHP_LIBMONGOC" == "no"; then backup_srcdir=${srcdir} srcdir=${srcdir}/src/libmongoc/ m4_include(src/libmongoc/build/autotools/Versions.m4) srcdir=${backup_srcdir} MONGOC_API_VERSION=1.0 AC_SUBST(MONGOC_MAJOR_VERSION) AC_SUBST(MONGOC_MINOR_VERSION) AC_SUBST(MONGOC_MICRO_VERSION) AC_SUBST(MONGOC_API_VERSION) AC_SUBST(MONGOC_VERSION) AC_OUTPUT($srcdir/src/libmongoc/src/mongoc/mongoc-config.h) AC_OUTPUT($srcdir/src/libmongoc/src/mongoc/mongoc-version.h) fi if test "$PHP_LIBBSON" == "no"; then backup_srcdir=${srcdir} srcdir=${srcdir}/src/libbson/ m4_include(src/libbson/build/autotools/Versions.m4) srcdir=${backup_srcdir} BSON_API_VERSION=1.0 AC_SUBST(BSON_MAJOR_VERSION) AC_SUBST(BSON_MINOR_VERSION) AC_SUBST(BSON_MICRO_VERSION) AC_SUBST(BSON_API_VERSION) AC_SUBST(BSON_VERSION) AC_OUTPUT($srcdir/src/libbson/src/bson/bson-config.h) AC_OUTPUT($srcdir/src/libbson/src/bson/bson-version.h) fi dnl This must come after PHP_NEW_EXTENSION, otherwise the srcdir won't be set PHP_ADD_MAKEFILE_FRAGMENT AC_CONFIG_COMMANDS_POST([echo " mongodb was configured with the following options: Build configuration: CFLAGS : $CFLAGS Extra CFLAGS : $STD_CFLAGS $EXTRA_CFLAGS Developers flags (slow) : $MAINTAINER_CFLAGS Code Coverage flags (extra slow) : $COVERAGE_CFLAGS System mongoc : $PHP_LIBMONGOC System libbson : $PHP_LIBBSON LDFLAGS : $LDFLAGS EXTRA_LDFLAGS : $EXTRA_LDFLAGS MONGODB_SHARED_LIBADD : $MONGODB_SHARED_LIBADD Please submit bugreports at: https://jira.mongodb.org/browse/PHPC "]) fi dnl: vim: et sw=2 mongodb-1.1.5/config.w320000664000175000017500000001066612673034026014621 0ustar jmikolajmikola// vim:ft=javascript ARG_ENABLE("mongodb", "MongoDB support", "no"); ARG_WITH("mongodb-sasl", "MongoDB: Build against Cyrus-SASL", "yes"); if (PHP_MONGODB != "no") { ADD_EXTENSION_DEP("mongodb", "openssl", false); ADD_FLAG("CFLAGS_MONGODB", " /I" + configure_module_dirname + " /I" + configure_module_dirname + "/src/libmongoc/src/mongoc" + " /I" + configure_module_dirname + "/src/libbson/src/bson/ /I" + configure_module_dirname + "/src/libbson/src /I" + configure_module_dirname + "/src/contrib /D HAVE_MONGODB_SASL=1 /D BSON_COMPILATION=1 /D MONGOC_COMPILATION=1 /D MONGOC_TRACE=1 /D MONGOC_NO_AUTOMATIC_GLOBALS=1 /D BSON_EXTRA_ALIGN=0"); EXTENSION("mongodb", "php_phongo.c"); ADD_SOURCES(configure_module_dirname + "/", "phongo_compat.c", "mongodb"); ADD_SOURCES(configure_module_dirname + "/src", "bson.c", "mongodb"); ADD_SOURCES(configure_module_dirname + "/src/BSON", "Type.c Unserializable.c Serializable.c Persistable.c Binary.c Javascript.c MaxKey.c MinKey.c ObjectID.c Regex.c Timestamp.c UTCDateTime.c", "mongodb"); ADD_SOURCES(configure_module_dirname + "/src/MongoDB", "Command.c Cursor.c CursorId.c Manager.c Query.c ReadConcern.c ReadPreference.c Server.c BulkWrite.c WriteConcern.c WriteConcernError.c WriteError.c WriteResult.c", "mongodb"); ADD_SOURCES(configure_module_dirname + "/src/MongoDB/Exception", "Exception.c LogicException.c RuntimeException.c UnexpectedValueException.c InvalidArgumentException.c ConnectionException.c AuthenticationException.c SSLConnectionException.c ExecutionTimeoutException.c ConnectionTimeoutException.c WriteException.c BulkWriteException.c", "mongodb"); ADD_SOURCES(configure_module_dirname + "/src/contrib/", "php-ssl.c", "mongodb"); ADD_SOURCES(configure_module_dirname + "/src/libbson/src/yajl", "yajl_version.c yajl.c yajl_encode.c yajl_lex.c yajl_parser.c yajl_buf.c yajl_tree.c yajl_alloc.c yajl_gen.c", "mongodb"); ADD_SOURCES(configure_module_dirname + "/src/libbson/src/bson", "bcon.c bson.c bson-atomic.c bson-clock.c bson-context.c bson-error.c bson-iter.c bson-iso8601.c bson-json.c bson-keys.c bson-md5.c bson-memory.c bson-oid.c bson-reader.c bson-string.c bson-timegm.c bson-utf8.c bson-value.c bson-version-functions.c bson-writer.c", "mongodb"); ADD_SOURCES(configure_module_dirname + "/src/libmongoc/src/mongoc", "mongoc-array.c mongoc-async.c mongoc-async-cmd.c mongoc-buffer.c mongoc-bulk-operation.c mongoc-b64.c mongoc-client.c mongoc-client-pool.c mongoc-cluster.c mongoc-collection.c mongoc-counters.c mongoc-cursor.c mongoc-cursor-array.c mongoc-cursor-transform.c mongoc-cursor-cursorid.c mongoc-database.c mongoc-find-and-modify.c mongoc-init.c mongoc-gridfs.c mongoc-gridfs-file.c mongoc-gridfs-file-page.c mongoc-gridfs-file-list.c mongoc-host-list.c mongoc-index.c mongoc-list.c mongoc-log.c mongoc-matcher-op.c mongoc-matcher.c mongoc-memcmp.c mongoc-opcode.c mongoc-queue.c mongoc-read-prefs.c mongoc-read-concern.c mongoc-rpc.c mongoc-set.c mongoc-server-description.c mongoc-server-stream.c mongoc-socket.c mongoc-stream.c mongoc-stream-buffered.c mongoc-stream-file.c mongoc-stream-gridfs.c mongoc-stream-socket.c mongoc-topology.c mongoc-topology-scanner.c mongoc-topology-description.c mongoc-uri.c mongoc-util.c mongoc-version-functions.c mongoc-write-command.c mongoc-write-concern.c", "mongodb"); ADD_SOURCES(configure_module_dirname + "/src/libmongoc/src/mongoc", "mongoc-rand.c mongoc-scram.c mongoc-stream-tls.c mongoc-ssl.c", "mongodb"); ADD_SOURCES(configure_module_dirname + "/src/libmongoc/src/mongoc", "mongoc-sasl.c", "mongodb"); AC_DEFINE("HAVE_MONGOC", 1); AC_DEFINE("MONGOC_HAVE_WEAK_SYMBOLS", 1); if (!CHECK_LIB("libsasl.lib", "mongodb", PHP_MONGODB)) { WARNING("mongodb libsasl support not enabled, libs not found"); } if (CHECK_LIB("ssleay32.lib", "mongodb", PHP_MONGODB) && CHECK_LIB("libeay32.lib", "mongodb", PHP_MONGODB) && CHECK_HEADER_ADD_INCLUDE("openssl/ssl.h", "CFLAGS_MONGOC")) { } FSO.CopyFile(configure_module_dirname + "/win32/bson-config.h", configure_module_dirname + "/src/libbson/src/bson/bson-config.h", true); FSO.CopyFile(configure_module_dirname + "/win32/bson-version.h", configure_module_dirname + "/src/libbson/src/bson/bson-version.h", true); FSO.CopyFile(configure_module_dirname + "/win32/mongoc-config.h", configure_module_dirname + "/src/libmongoc/src/mongoc/mongoc-config.h", true); FSO.CopyFile(configure_module_dirname + "/win32/mongoc-version.h", configure_module_dirname + "/src/libmongoc/src/mongoc/mongoc-version.h", true); } mongodb-1.1.5/phongo_compat.c0000664000175000017500000000455312673034026016016 0ustar jmikolajmikola/* +---------------------------------------------------------------------------+ | PHP Driver for MongoDB | +---------------------------------------------------------------------------+ | Copyright 2013-2015 MongoDB, Inc. | | | | Licensed under the Apache License, Version 2.0 (the "License"); | | you may not use this file except in compliance with the License. | | You may obtain a copy of the License at | | | | http://www.apache.org/licenses/LICENSE-2.0 | | | | Unless required by applicable law or agreed to in writing, software | | distributed under the License is distributed on an "AS IS" BASIS, | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | See the License for the specific language governing permissions and | | limitations under the License. | +---------------------------------------------------------------------------+ | Copyright (c) 2015 MongoDB, Inc. | +---------------------------------------------------------------------------+ */ /* Our Compatability header */ #include "phongo_compat.h" void *x509_from_zval(zval *zval TSRMLS_DC) { #if PHP_VERSION_ID >= 70000 return Z_RES_P(zval)->ptr; #else int resource_type; int type; zend_list_find(Z_LVAL_P(zval), &resource_type); return zend_fetch_resource(&zval TSRMLS_CC, -1, "OpenSSL X.509", &type, 1, resource_type); #endif } void phongo_add_exception_prop(const char *prop, int prop_len, zval *value TSRMLS_DC) { if (EG(exception)) { #if PHP_VERSION_ID >= 70000 zval ex; EXCEPTION_P(EG(exception), ex); zend_update_property(Z_OBJCE(ex), &ex, prop, prop_len, value); #else zval *ex = NULL; EXCEPTION_P(EG(exception), ex); zend_update_property(Z_OBJCE_P(ex), ex, prop, prop_len, value TSRMLS_CC); #endif } } /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mongodb-1.1.5/phongo_compat.h0000664000175000017500000002272212673034026016021 0ustar jmikolajmikola/* +---------------------------------------------------------------------------+ | PHP Driver for MongoDB | +---------------------------------------------------------------------------+ | Copyright 2013-2015 MongoDB, Inc. | | | | Licensed under the Apache License, Version 2.0 (the "License"); | | you may not use this file except in compliance with the License. | | You may obtain a copy of the License at | | | | http://www.apache.org/licenses/LICENSE-2.0 | | | | Unless required by applicable law or agreed to in writing, software | | distributed under the License is distributed on an "AS IS" BASIS, | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | See the License for the specific language governing permissions and | | limitations under the License. | +---------------------------------------------------------------------------+ | Copyright (c) 2015 MongoDB, Inc. | +---------------------------------------------------------------------------+ */ #ifndef PHONGO_COMPAT_H #define PHONGO_COMPAT_H #include #include #if PHP_VERSION_ID >= 70000 #include #endif #ifdef PHP_WIN32 # include "config.w32.h" #else # include #endif #ifndef PHP_FE_END # define PHP_FE_END { NULL, NULL, NULL } #endif #ifndef HASH_KEY_NON_EXISTENT # define HASH_KEY_NON_EXISTENT HASH_KEY_NON_EXISTANT #endif #if PHP_VERSION_ID < 50400 # define object_properties_init(_std, _class_type) \ zend_hash_copy(*_std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *)); #endif #if PHP_VERSION_ID >= 70000 # define str_efree(s) efree((char*)s) #elif PHP_VERSION_ID < 50400 # define str_efree(s) efree((char*)s) #else # include #endif #if PHP_VERSION_ID >= 50500 #define ITERATOR_GET_CURRENT_KEY(it, z) \ (it).funcs->get_current_key(&(it), z TSRMLS_CC); #else #define ITERATOR_GET_CURRENT_KEY(it, z) \ { \ char *str_key; \ uint str_key_len; \ ulong int_key; \ switch ((it).funcs->get_current_key(&(it), &str_key, &str_key_len, &int_key TSRMLS_CC)) { \ case HASH_KEY_IS_LONG: \ ZVAL_LONG(z, int_key); \ break; \ case HASH_KEY_IS_STRING: \ ZVAL_STRINGL(z, str_key, str_key_len-1, 0); \ break; \ default: \ RETURN_NULL(); \ } \ } #endif /* There was a very bad bug in 5.6.0 through 5.6.6 downgrading * METHOD_SSLv23 to SSLv2 and SSLv3 exclusively */ #if PHP_VERSION_ID >= 50600 && PHP_VERSION_ID < 50607 # define PHONGO_CRYPTO_METHOD STREAM_CRYPTO_METHOD_ANY_CLIENT #else # define PHONGO_CRYPTO_METHOD STREAM_CRYPTO_METHOD_SSLv23_CLIENT #endif #if defined(__GNUC__) # define ARG_UNUSED __attribute__ ((unused)) #else # define ARG_UNUSED #endif #ifdef HAVE_ATOLL # define STRTOLL(s) atoll(s) #else # if defined(PHP_WIN32) # define STRTOLL(s) _atoi64(s) # else # define STRTOLL(s) strtoll(s, NULL, 10) # endif #endif #if PHP_VERSION_ID < 50400 # define GET_DEFAULT_CONTEXT() \ ctx = FG(default_context) ? FG(default_context) : php_stream_context_alloc() #else # define GET_DEFAULT_CONTEXT() \ ctx = FG(default_context) ? FG(default_context) : php_stream_context_alloc(TSRMLS_C) #endif #ifndef php_ignore_value # if defined(__GNUC__) && __GNUC__ >= 4 # define php_ignore_value(x) (({ __typeof__ (x) __x = (x); (void) __x; })) # else # define php_ignore_value(x) ((void) (x)) # endif #endif #if PHP_VERSION_ID >= 70000 # define phongo_char zend_string # define phongo_char_pdup(str) pestrdup(filename->val, 1) # define phongo_char_free(str) zend_string_release(str) # define phongo_long zend_long #if SIZEOF_ZEND_LONG == 8 # define PHONGO_LONG_FORMAT PRId64 #elif SIZEOF_ZEND_LONG == 4 # define PHONGO_LONG_FORMAT PRId32 #else # error Unsupported architecture (integers are neither 32-bit nor 64-bit) #endif # define SIZEOF_PHONGO_LONG SIZEOF_ZEND_LONG # define phongo_str(str) str->val # define phongo_create_object_retval zend_object* # define PHONGO_ALLOC_OBJECT_T(_obj_t, _class_type) (_obj_t *)ecalloc(1, sizeof(_obj_t)+zend_object_properties_size(_class_type)) # define PHONGO_TSRMLS_FETCH_FROM_CTX(user_data) # define SUPPRESS_UNUSED_WARNING(x) # define DECLARE_RETURN_VALUE_USED int return_value_used = 1; # define EXCEPTION_P(_ex, _zp) ZVAL_OBJ(&_zp, _ex) # define PHONGO_STREAM_ID(stream) stream->res ? stream->res->handle : -1 # define ADD_ASSOC_STRING(_zv, _key, _value) add_assoc_string_ex(_zv, ZEND_STRL(_key), _value); # define ADD_ASSOC_STRINGL(_zv, _key, _value, _len) add_assoc_stringl_ex(_zv, ZEND_STRL(_key), _value, _len); # define ADD_ASSOC_LONG_EX(_zv, _key, _value) add_assoc_long_ex(_zv, ZEND_STRL(_key), _value); # define ADD_ASSOC_STRING_EX(_zv, _key, _key_len, _value, _value_len) add_assoc_stringl_ex(_zv, _key, _key_len, _value, _value_len); # define ADD_ASSOC_ZVAL_EX(_zv, _key, _value) add_assoc_zval_ex(_zv, ZEND_STRL(_key), _value); # define ADD_ASSOC_ZVAL(_zv, _key, _value) add_assoc_zval(_zv, _key, _value); # define ADD_ASSOC_NULL_EX(_zv, _key) add_assoc_null_ex(_zv, ZEND_STRL(_key)); # define ADD_ASSOC_BOOL_EX(_zv, _key, _value) add_assoc_bool_ex(_zv, ZEND_STRL(_key), _value); # define ADD_INDEX_STRINGL(_zv, _ind, _value, _len) add_index_stringl(_zv, _ind, _value, _len); # define phongo_free_object_arg zend_object # define phongo_zpp_char_len size_t # define ZEND_HASH_APPLY_COUNT(ht) (ht)->u.v.nApplyCount # define PHONGO_RETVAL_STRINGL(s, slen) RETVAL_STRINGL(s, slen) # define PHONGO_RETURN_STRINGL(s, slen) RETURN_STRINGL(s, slen) # define PHONGO_RETURN_STRING(s) RETURN_STRING(s) #else # define phongo_char char # define phongo_char_pdup(str) pestrdup(filename, 1) # define phongo_char_free(str) _efree(str ZEND_FILE_LINE_CC ZEND_FILE_LINE_CC) # define phongo_long long # define PHONGO_LONG_FORMAT "ld" # define SIZEOF_PHONGO_LONG SIZEOF_LONG # define phongo_str(str) str # define phongo_create_object_retval zend_object_value # define PHONGO_ALLOC_OBJECT_T(_obj_t, _class_type) (_obj_t *)ecalloc(1, sizeof(_obj_t)) # define PHONGO_TSRMLS_FETCH_FROM_CTX(user_data) TSRMLS_FETCH_FROM_CTX(user_data) # define SUPPRESS_UNUSED_WARNING(x) (void)x; # define DECLARE_RETURN_VALUE_USED # define EXCEPTION_P(_ex, _zp) _zp = _ex # define PHONGO_STREAM_ID(stream) stream->rsrc_id # define ADD_ASSOC_STRING(_zv, _key, _value) add_assoc_string_ex(_zv, ZEND_STRS(_key), _value, 1); # define ADD_ASSOC_STRINGL(_zv, _key, _value, _len) add_assoc_stringl_ex(_zv, ZEND_STRS(_key), _value, _len, 1); # define ADD_ASSOC_STRING_EX(_zv, _key, _key_len, _value, _value_len) add_assoc_stringl_ex(_zv, _key, _key_len+1, _value, _value_len, 1); # define ADD_ASSOC_LONG_EX(_zv, _key, _value) add_assoc_long_ex(_zv, ZEND_STRS(_key), _value); # define ADD_ASSOC_ZVAL_EX(_zv, _key, _value) add_assoc_zval_ex(_zv, ZEND_STRS(_key), _value); # define ADD_ASSOC_ZVAL(_zv, _key, _value) add_assoc_zval(_zv, _key, _value); # define ADD_ASSOC_NULL_EX(_zv, _key) add_assoc_null_ex(_zv, ZEND_STRS(_key)); # define ADD_ASSOC_BOOL_EX(_zv, _key, _value) add_assoc_bool_ex(_zv, ZEND_STRS(_key), _value); # define ADD_INDEX_STRINGL(_zv, _ind, _value, _len) add_index_stringl(_zv, _ind, _value, _len, 0); # define Z_PHPDATE_P(object) zend_object_store_get_object(object TSRMLS_CC) # define Z_ISUNDEF(x) !x # define phongo_free_object_arg void # define phongo_zpp_char_len int # define ZEND_HASH_APPLY_COUNT(ht) (ht)->nApplyCount # define PHONGO_RETVAL_STRINGL(s, slen) RETVAL_STRINGL(s, slen, 1) # define PHONGO_RETURN_STRINGL(s, slen) RETURN_STRINGL(s, slen, 1) # define PHONGO_RETURN_STRING(s) RETURN_STRING(s, 1) # define PHP_STREAM_CONTEXT(stream) ((php_stream_context*) (stream)->context) #endif #if SIZEOF_PHONGO_LONG == 8 # define ADD_INDEX_INT64(zval, index, value) add_index_long(zval, index, value) # define ADD_ASSOC_INT64(zval, key, value) add_assoc_long(zval, key, value) #elif SIZEOF_PHONGO_LONG == 4 # define ADD_INDEX_INT64(zval, index, value) \ if (value > INT32_MAX || value < INT32_MIN) { \ char *tmp; \ int tmp_len; \ mongoc_log(MONGOC_LOG_LEVEL_WARNING, MONGOC_LOG_DOMAIN, "Integer overflow detected on your platform: %lld", value); \ tmp_len = spprintf(&tmp, 0, "%lld", value); \ ADD_INDEX_STRINGL(zval, index, tmp, tmp_len); \ efree(tmp); \ } else { \ add_index_long(zval, index, val); \ } # define ADD_ASSOC_INT64(zval, key, value) \ if (value > INT32_MAX || value < INT32_MIN) { \ char *tmp; \ int tmp_len; \ mongoc_log(MONGOC_LOG_LEVEL_WARNING, MONGOC_LOG_DOMAIN, "Integer overflow detected on your platform: %lld", value); \ tmp_len = spprintf(&tmp, 0, "%lld", value); \ ADD_ASSOC_STRING_EX(zval, key, strlen(key), tmp, tmp_len); \ efree(tmp); \ } else { \ add_assoc_long(zval, key, value); \ } #else # error Unsupported architecture (integers are neither 32-bit nor 64-bit) #endif void *x509_from_zval(zval *zval TSRMLS_DC); void phongo_add_exception_prop(const char *prop, int prop_len, zval *value TSRMLS_DC); #endif /* PHONGO_COMPAT_H */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mongodb-1.1.5/php_bson.h0000664000175000017500000000660212673034026014773 0ustar jmikolajmikola/* +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ | Copyright (c) 20142015 Hannes Magnusson | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Hannes Magnusson | +----------------------------------------------------------------------+ */ /* $Id$ */ #ifndef PHONGO_BSON_H #define PHONGO_BSON_H #include /* PHP Core stuff */ #include /* Check if we are part of pecl/mongodb or standalone (pecl/bson) */ #ifdef HAVE_MONGOC #define BSON_NAMESPACE "MongoDB\\BSON" #else #define BSON_NAMESPACE "BSON" #endif #define BSON_UNSERIALIZE_FUNC_NAME "bsonUnserialize" #define BSON_SERIALIZE_FUNC_NAME "bsonSerialize" typedef enum { PHONGO_BSON_NONE = 0x00, PHONGO_BSON_ADD_ID = 0x01, PHONGO_BSON_RETURN_ID = 0x02 } php_phongo_bson_flags_t; typedef enum { PHONGO_TYPEMAP_NONE, PHONGO_TYPEMAP_NATIVE_ARRAY, PHONGO_TYPEMAP_NATIVE_OBJECT, PHONGO_TYPEMAP_CLASS } php_phongo_bson_typemap_types; typedef struct { php_phongo_bson_typemap_types document_type; zend_class_entry *document; php_phongo_bson_typemap_types array_type; zend_class_entry *array; php_phongo_bson_typemap_types root_type; zend_class_entry *root; } php_phongo_bson_typemap; typedef struct { #if PHP_VERSION_ID >= 70000 zval zchild; #else zval *zchild; #endif php_phongo_bson_typemap map; zend_class_entry *odm; } php_phongo_bson_state; #if PHP_VERSION_ID >= 70000 #define PHONGO_BSON_STATE_INITIALIZER { {{ 0 }}, { PHONGO_TYPEMAP_NONE, NULL, PHONGO_TYPEMAP_NONE, NULL, PHONGO_TYPEMAP_NONE, NULL}, NULL} #else #define PHONGO_BSON_STATE_INITIALIZER { NULL, { PHONGO_TYPEMAP_NONE, NULL, PHONGO_TYPEMAP_NONE, NULL, PHONGO_TYPEMAP_NONE, NULL}, NULL} #endif PHONGO_API void phongo_zval_to_bson(zval *data, php_phongo_bson_flags_t flags, bson_t *bson, bson_t **bson_out TSRMLS_DC); PHONGO_API int phongo_bson_to_zval_ex(const unsigned char *data, int data_len, php_phongo_bson_state *state); #if PHP_VERSION_ID >= 70000 PHONGO_API int phongo_bson_to_zval(const unsigned char *data, int data_len, zval *out); #else PHONGO_API int phongo_bson_to_zval(const unsigned char *data, int data_len, zval **out); #endif PHONGO_API void phongo_bson_typemap_to_state(zval *typemap, php_phongo_bson_typemap *map TSRMLS_DC); PHP_FUNCTION(toPHP); PHP_FUNCTION(fromPHP); PHP_FUNCTION(toJSON); PHP_FUNCTION(fromJSON); #endif /* PHONGO_BSON_H */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mongodb-1.1.5/php_phongo.c0000664000175000017500000023656712673034026015336 0ustar jmikolajmikola/* +---------------------------------------------------------------------------+ | PHP Driver for MongoDB | +---------------------------------------------------------------------------+ | Copyright 2013-2015 MongoDB, Inc. | | | | Licensed under the Apache License, Version 2.0 (the "License"); | | you may not use this file except in compliance with the License. | | You may obtain a copy of the License at | | | | http://www.apache.org/licenses/LICENSE-2.0 | | | | Unless required by applicable law or agreed to in writing, software | | distributed under the License is distributed on an "AS IS" BASIS, | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | See the License for the specific language governing permissions and | | limitations under the License. | +---------------------------------------------------------------------------+ | Copyright (c) 2014-2015 MongoDB, Inc. | +---------------------------------------------------------------------------+ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif /* External libs */ #include "bson.h" #include "mongoc.h" #include "mongoc-cursor-cursorid-private.h" #include "mongoc-read-prefs-private.h" #include "mongoc-bulk-operation-private.h" #include "mongoc-read-concern-private.h" #include "mongoc-write-concern-private.h" #include "mongoc-uri-private.h" #include "mongoc-trace.h" /* PHP Core stuff */ #include #include #include #include #include #include #include #include #include /* Stream wrapper */ #include

#include
/* Debug log writing */ #include
/* For formating timestamp in the log */ #include /* String manipulation */ #include /* PHP array helpers */ #include "php_array_api.h" /* For our stream verifications */ #include /* Our Compatability header */ #include "phongo_compat.h" /* Our stuffz */ #include "php_phongo.h" #include "php_bson.h" #include "php-ssl.h" #undef MONGOC_LOG_DOMAIN #define MONGOC_LOG_DOMAIN "PHONGO" #define PHONGO_DEBUG_INI "mongodb.debug" #define PHONGO_DEBUG_INI_DEFAULT "" #define PHONGO_STREAM_BUFFER_SIZE 4096 ZEND_DECLARE_MODULE_GLOBALS(mongodb) #if PHP_VERSION_ID >= 70000 #if defined(ZTS) && defined(COMPILE_DL_MONGODB) ZEND_TSRMLS_CACHE_DEFINE(); #endif #endif /* {{{ phongo_std_object_handlers */ zend_object_handlers phongo_std_object_handlers; PHONGO_API zend_object_handlers *phongo_get_std_object_handlers(void) { return &phongo_std_object_handlers; } /* }}} */ /* {{{ Error reporting and logging */ zend_class_entry* phongo_exception_from_phongo_domain(php_phongo_error_domain_t domain) { switch (domain) { case PHONGO_ERROR_INVALID_ARGUMENT: return php_phongo_invalidargumentexception_ce; case PHONGO_ERROR_LOGIC: return php_phongo_logicexception_ce; case PHONGO_ERROR_RUNTIME: return php_phongo_runtimeexception_ce; case PHONGO_ERROR_UNEXPECTED_VALUE: return php_phongo_unexpectedvalueexception_ce; case PHONGO_ERROR_MONGOC_FAILED: return php_phongo_runtimeexception_ce; case PHONGO_ERROR_WRITE_FAILED: return php_phongo_bulkwriteexception_ce; case PHONGO_ERROR_CONNECTION_FAILED: return php_phongo_connectionexception_ce; } MONGOC_ERROR("Resolving unknown phongo error domain: %d", domain); return php_phongo_runtimeexception_ce; } zend_class_entry* phongo_exception_from_mongoc_domain(uint32_t /* mongoc_error_domain_t */ domain, uint32_t /* mongoc_error_code_t */ code) { switch(code) { case 50: /* ExceededTimeLimit */ return php_phongo_executiontimeoutexception_ce; case MONGOC_ERROR_STREAM_SOCKET: case MONGOC_ERROR_SERVER_SELECTION_FAILURE: return php_phongo_connectiontimeoutexception_ce; case MONGOC_ERROR_CLIENT_AUTHENTICATE: return php_phongo_authenticationexception_ce; case MONGOC_ERROR_STREAM_INVALID_TYPE: case MONGOC_ERROR_STREAM_INVALID_STATE: case MONGOC_ERROR_STREAM_NAME_RESOLUTION: case MONGOC_ERROR_STREAM_CONNECT: case MONGOC_ERROR_STREAM_NOT_ESTABLISHED: return php_phongo_connectionexception_ce; case MONGOC_ERROR_CLIENT_NOT_READY: case MONGOC_ERROR_CLIENT_TOO_BIG: case MONGOC_ERROR_CLIENT_TOO_SMALL: case MONGOC_ERROR_CLIENT_GETNONCE: case MONGOC_ERROR_CLIENT_NO_ACCEPTABLE_PEER: case MONGOC_ERROR_CLIENT_IN_EXHAUST: case MONGOC_ERROR_PROTOCOL_INVALID_REPLY: case MONGOC_ERROR_PROTOCOL_BAD_WIRE_VERSION: case MONGOC_ERROR_CURSOR_INVALID_CURSOR: case MONGOC_ERROR_QUERY_FAILURE: /*case MONGOC_ERROR_PROTOCOL_ERROR:*/ case MONGOC_ERROR_BSON_INVALID: case MONGOC_ERROR_MATCHER_INVALID: case MONGOC_ERROR_NAMESPACE_INVALID: case MONGOC_ERROR_COMMAND_INVALID_ARG: case MONGOC_ERROR_COLLECTION_INSERT_FAILED: case MONGOC_ERROR_GRIDFS_INVALID_FILENAME: case MONGOC_ERROR_QUERY_COMMAND_NOT_FOUND: case MONGOC_ERROR_QUERY_NOT_TAILABLE: return php_phongo_runtimeexception_ce; } switch (domain) { case MONGOC_ERROR_CLIENT: case MONGOC_ERROR_STREAM: case MONGOC_ERROR_PROTOCOL: case MONGOC_ERROR_CURSOR: case MONGOC_ERROR_QUERY: case MONGOC_ERROR_INSERT: case MONGOC_ERROR_SASL: case MONGOC_ERROR_BSON: case MONGOC_ERROR_MATCHER: case MONGOC_ERROR_NAMESPACE: case MONGOC_ERROR_COMMAND: case MONGOC_ERROR_COLLECTION: case MONGOC_ERROR_GRIDFS: /* FIXME: We don't have the Exceptions mocked yet.. */ #if 0 return phongo_ce_mongo_connection_exception; #endif default: return php_phongo_runtimeexception_ce; } } void phongo_throw_exception(php_phongo_error_domain_t domain TSRMLS_DC, const char *format, ...) { va_list args; char *message; int message_len; va_start(args, format); message_len = vspprintf(&message, 0, format, args); zend_throw_exception(phongo_exception_from_phongo_domain(domain), message, 0 TSRMLS_CC); efree(message); va_end(args); } void phongo_throw_exception_from_bson_error_t(bson_error_t *error TSRMLS_DC) { zend_throw_exception(phongo_exception_from_mongoc_domain(error->domain, error->code), error->message, error->code TSRMLS_CC); } static void php_phongo_log(mongoc_log_level_t log_level, const char *log_domain, const char *message, void *user_data) { PHONGO_TSRMLS_FETCH_FROM_CTX(user_data); (void)user_data; switch(log_level) { case MONGOC_LOG_LEVEL_ERROR: case MONGOC_LOG_LEVEL_CRITICAL: phongo_throw_exception(PHONGO_ERROR_MONGOC_FAILED TSRMLS_CC, "%s", message); return; case MONGOC_LOG_LEVEL_WARNING: case MONGOC_LOG_LEVEL_MESSAGE: case MONGOC_LOG_LEVEL_INFO: case MONGOC_LOG_LEVEL_DEBUG: case MONGOC_LOG_LEVEL_TRACE: { time_t t; phongo_char *dt; time(&t); dt = php_format_date((char *)"Y-m-d\\TH:i:sP", strlen("Y-m-d\\TH:i:sP"), t, 0 TSRMLS_CC); fprintf(MONGODB_G(debug_fd), "[%s] %10s: %-8s> %s\n", phongo_str(dt), log_domain, mongoc_log_level_str(log_level), message); fflush(MONGODB_G(debug_fd)); efree(dt); } break; } } /* }}} */ /* {{{ Init objects */ static void phongo_cursor_init(zval *return_value, mongoc_cursor_t *cursor, mongoc_client_t *client TSRMLS_DC) /* {{{ */ { php_phongo_cursor_t *intern; object_init_ex(return_value, php_phongo_cursor_ce); intern = Z_CURSOR_OBJ_P(return_value); intern->cursor = cursor; intern->server_id = mongoc_cursor_get_hint(cursor); intern->client = client; } /* }}} */ void phongo_server_init(zval *return_value, mongoc_client_t *client, int server_id TSRMLS_DC) /* {{{ */ { php_phongo_server_t *server; object_init_ex(return_value, php_phongo_server_ce); server = Z_SERVER_OBJ_P(return_value); server->client = client; server->server_id = server_id; } /* }}} */ void phongo_readconcern_init(zval *return_value, const mongoc_read_concern_t *read_concern TSRMLS_DC) /* {{{ */ { php_phongo_readconcern_t *intern; object_init_ex(return_value, php_phongo_readconcern_ce); intern = Z_READCONCERN_OBJ_P(return_value); intern->read_concern = mongoc_read_concern_copy(read_concern); } /* }}} */ void phongo_readpreference_init(zval *return_value, const mongoc_read_prefs_t *read_prefs TSRMLS_DC) /* {{{ */ { php_phongo_readpreference_t *intern; object_init_ex(return_value, php_phongo_readpreference_ce); intern = Z_READPREFERENCE_OBJ_P(return_value); intern->read_preference = mongoc_read_prefs_copy(read_prefs); } /* }}} */ void phongo_writeconcern_init(zval *return_value, const mongoc_write_concern_t *write_concern TSRMLS_DC) /* {{{ */ { php_phongo_writeconcern_t *intern; object_init_ex(return_value, php_phongo_writeconcern_ce); intern = Z_WRITECONCERN_OBJ_P(return_value); intern->write_concern = mongoc_write_concern_copy(write_concern); } /* }}} */ int32_t phongo_bson_find_as_int32(bson_t *bson, const char *key, int32_t fallback) { bson_iter_t iter; if (bson_iter_init_find(&iter, bson, key) && BSON_ITER_HOLDS_INT32(&iter)) { return bson_iter_int32(&iter); } return fallback; } bool phongo_bson_find_as_bool(bson_t *bson, const char *key, bool fallback) { bson_iter_t iter; if (bson_iter_init_find(&iter, bson, key) && BSON_ITER_HOLDS_BOOL(&iter)) { return bson_iter_bool(&iter); } return fallback; } void phongo_bson_iter_as_document(const bson_iter_t *iter, uint32_t *document_len, const uint8_t **document) { *document = NULL; *document_len = 0; if (BSON_ITER_HOLDS_DOCUMENT(iter) || BSON_ITER_HOLDS_ARRAY(iter)) { memcpy (document_len, (iter->raw + iter->d1), sizeof (*document_len)); *document_len = BSON_UINT32_FROM_LE (*document_len); *document = (iter->raw + iter->d1); } } bool phongo_query_init(php_phongo_query_t *query, bson_t *filter, bson_t *options TSRMLS_DC) /* {{{ */ { bson_iter_t iter; if (options) { query->batch_size = phongo_bson_find_as_int32(options, "batchSize", 0); query->limit = phongo_bson_find_as_int32(options, "limit", 0); query->skip = phongo_bson_find_as_int32(options, "skip", 0); query->flags = 0; query->flags |= phongo_bson_find_as_bool(options, "tailable", false) ? MONGOC_QUERY_TAILABLE_CURSOR : 0; query->flags |= phongo_bson_find_as_bool(options, "slaveOk", false) ? MONGOC_QUERY_SLAVE_OK : 0; query->flags |= phongo_bson_find_as_bool(options, "oplogReplay", false) ? MONGOC_QUERY_OPLOG_REPLAY : 0; query->flags |= phongo_bson_find_as_bool(options, "noCursorTimeout", false) ? MONGOC_QUERY_NO_CURSOR_TIMEOUT : 0; query->flags |= phongo_bson_find_as_bool(options, "awaitData", false) ? MONGOC_QUERY_AWAIT_DATA : 0; query->flags |= phongo_bson_find_as_bool(options, "exhaust", false) ? MONGOC_QUERY_EXHAUST : 0; query->flags |= phongo_bson_find_as_bool(options, "partial", false) ? MONGOC_QUERY_PARTIAL : 0; if (bson_iter_init_find(&iter, options, "modifiers")) { uint32_t len = 0; const uint8_t *data = NULL; if (! (BSON_ITER_HOLDS_DOCUMENT (&iter) || BSON_ITER_HOLDS_ARRAY (&iter))) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected modifiers to be array or object, %d given", bson_iter_type(&iter)); return false; } bson_iter_document(&iter, &len, &data); if (len) { bson_t tmp; bson_init_static(&tmp, data, len); bson_copy_to_excluding_noinit(&tmp, query->query, "not-used-value", NULL); bson_destroy (&tmp); } } if (bson_iter_init_find(&iter, options, "projection")) { uint32_t len = 0; const uint8_t *data = NULL; if (! (BSON_ITER_HOLDS_DOCUMENT (&iter) || BSON_ITER_HOLDS_ARRAY (&iter))) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected projection to be array or object, %d given", bson_iter_type(&iter)); return false; } bson_iter_document(&iter, &len, &data); if (len) { query->selector = bson_new_from_data(data, len); } } if (bson_iter_init_find(&iter, options, "sort")) { uint32_t len = 0; const uint8_t *data = NULL; if (! (BSON_ITER_HOLDS_DOCUMENT (&iter) || BSON_ITER_HOLDS_ARRAY (&iter))) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Expected sort to be array or object, %d given", bson_iter_type(&iter)); return false; } phongo_bson_iter_as_document(&iter, &len, &data); if (len) { bson_t tmp; bson_init_static(&tmp, data, len); bson_append_document(query->query, "$orderby", -1, &tmp); bson_destroy(&tmp); } } } BSON_APPEND_DOCUMENT(query->query, "$query", filter); return true; } /* }}} */ zend_bool phongo_writeconcernerror_init(zval *return_value, bson_t *bson TSRMLS_DC) /* {{{ */ { bson_iter_t iter; php_phongo_writeconcernerror_t *writeconcernerror; writeconcernerror = Z_WRITECONCERNERROR_OBJ_P(return_value); if (bson_iter_init_find(&iter, bson, "code") && BSON_ITER_HOLDS_INT32(&iter)) { writeconcernerror->code = bson_iter_int32(&iter); } if (bson_iter_init_find(&iter, bson, "errmsg") && BSON_ITER_HOLDS_UTF8(&iter)) { writeconcernerror->message = bson_iter_dup_utf8(&iter, NULL); } if (bson_iter_init_find(&iter, bson, "errInfo") && BSON_ITER_HOLDS_DOCUMENT(&iter)) { uint32_t len; const uint8_t *data; bson_iter_document(&iter, &len, &data); if (!data) { return false; } if (!phongo_bson_to_zval(data, len, &writeconcernerror->info)) { zval_ptr_dtor(&writeconcernerror->info); #if PHP_VERSION_ID >= 70000 ZVAL_UNDEF(&writeconcernerror->info); #else writeconcernerror->info = NULL; #endif return false; } } return true; } /* }}} */ zend_bool phongo_writeerror_init(zval *return_value, bson_t *bson TSRMLS_DC) /* {{{ */ { bson_iter_t iter; php_phongo_writeerror_t *writeerror; writeerror = Z_WRITEERROR_OBJ_P(return_value); if (bson_iter_init_find(&iter, bson, "code") && BSON_ITER_HOLDS_INT32(&iter)) { writeerror->code = bson_iter_int32(&iter); } if (bson_iter_init_find(&iter, bson, "errmsg") && BSON_ITER_HOLDS_UTF8(&iter)) { writeerror->message = bson_iter_dup_utf8(&iter, NULL); } if (bson_iter_init_find(&iter, bson, "errInfo")) { bson_t info; bson_init(&info); bson_append_iter(&info, NULL, 0, &iter); if (!phongo_bson_to_zval(bson_get_data(&info), info.len, &writeerror->info)) { zval_ptr_dtor(&writeerror->info); #if PHP_VERSION_ID >= 70000 ZVAL_UNDEF(&writeerror->info); #else writeerror->info = NULL; #endif return false; } } if (bson_iter_init_find(&iter, bson, "index") && BSON_ITER_HOLDS_INT32(&iter)) { writeerror->index = bson_iter_int32(&iter); } return true; } /* }}} */ php_phongo_writeresult_t *phongo_writeresult_init(zval *return_value, mongoc_write_result_t *write_result, mongoc_client_t *client, int server_id TSRMLS_DC) /* {{{ */ { php_phongo_writeresult_t *writeresult; object_init_ex(return_value, php_phongo_writeresult_ce); writeresult = Z_WRITERESULT_OBJ_P(return_value); writeresult->client = client; writeresult->server_id = server_id; /* Copy write_results or else it'll get destroyed with the bulk destruction */ #define SCP(field) writeresult->write_result.field = write_result->field SCP(omit_nModified); SCP(nInserted); SCP(nMatched); SCP(nModified); SCP(nRemoved); SCP(nUpserted); bson_copy_to(&write_result->upserted, &writeresult->write_result.upserted); SCP(n_writeConcernErrors); bson_copy_to(&write_result->writeConcernErrors, &writeresult->write_result.writeConcernErrors); bson_copy_to(&write_result->writeErrors, &writeresult->write_result.writeErrors); SCP(upsert_append_count); #undef SCP return writeresult; } /* }}} */ /* }}} */ /* {{{ CRUD */ /* Splits a namespace name into the database and collection names, allocated with estrdup. */ bool phongo_split_namespace(const char *namespace, char **dbname, char **cname) /* {{{ */ { char *dot = strchr(namespace, '.'); if (!dot) { return false; } if (cname) { *cname = estrdup(namespace + (dot - namespace) + 1); } if (dbname) { *dbname = estrndup(namespace, dot - namespace); } return true; } /* }}} */ mongoc_bulk_operation_t *phongo_bulkwrite_init(zend_bool ordered) { /* {{{ */ return mongoc_bulk_operation_new(ordered); } /* }}} */ static void phongo_bulk_write_error_add_message(char **tmp_msg, bson_t *errors) { bson_iter_t iter; bson_iter_init(&iter, errors); while (bson_iter_next(&iter)) { bson_t cbson; uint32_t len; const uint8_t *data; bson_iter_t inner_iter; if (!BSON_ITER_HOLDS_DOCUMENT(&iter)) { continue; } bson_iter_document(&iter, &len, &data); if (!bson_init_static(&cbson, data, len)) { continue; } if (bson_iter_init_find(&inner_iter, &cbson, "errmsg") && BSON_ITER_HOLDS_UTF8(&inner_iter)) { const char *tmp_errmsg = bson_iter_utf8(&inner_iter, NULL); size_t tmp_errmsg_len = strlen(tmp_errmsg); *tmp_msg = erealloc(*tmp_msg, strlen(*tmp_msg) + tmp_errmsg_len + 5); strncpy(*tmp_msg + strlen(*tmp_msg), " :: ", 5); strncpy(*tmp_msg + strlen(*tmp_msg), tmp_errmsg, tmp_errmsg_len + 1); } } } static char* phongo_assemble_bulk_write_error(mongoc_write_result_t *write_result) { char *tmp_msg = emalloc(sizeof("BulkWrite error")); strncpy(tmp_msg, "BulkWrite error", sizeof("BulkWrite error")); if (!bson_empty0(&write_result->writeErrors)) { phongo_bulk_write_error_add_message(&tmp_msg, &write_result->writeErrors); } if (!bson_empty0(&write_result->writeConcernErrors)) { phongo_bulk_write_error_add_message(&tmp_msg, &write_result->writeConcernErrors); } return tmp_msg; } bool phongo_execute_write(mongoc_client_t *client, const char *namespace, mongoc_bulk_operation_t *bulk, const mongoc_write_concern_t *write_concern, int server_id, zval *return_value, int return_value_used TSRMLS_DC) /* {{{ */ { bson_error_t error; char *dbname; char *collname; int success; php_phongo_writeresult_t *writeresult; if (!phongo_split_namespace(namespace, &dbname, &collname)) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s: %s", "Invalid namespace provided", namespace); return false; } mongoc_bulk_operation_set_database(bulk, dbname); mongoc_bulk_operation_set_collection(bulk, collname); mongoc_bulk_operation_set_client(bulk, client); /* If a write concern was not specified, libmongoc will use the client's * write concern; however, we should still fetch it for the write result. */ if (write_concern) { mongoc_bulk_operation_set_write_concern(bulk, write_concern); } else { write_concern = mongoc_client_get_write_concern(client); } efree(dbname); efree(collname); if (server_id > 0) { mongoc_bulk_operation_set_hint(bulk, server_id); } success = mongoc_bulk_operation_execute(bulk, NULL, &error); /* Write succeeded and the user doesn't care for the results */ if (success && !return_value_used) { return true; } /* Check for connection related exceptions */ if (EG(exception)) { return false; } writeresult = phongo_writeresult_init(return_value, &bulk->result, client, bulk->hint TSRMLS_CC); writeresult->write_concern = mongoc_write_concern_copy(write_concern); /* The Write failed */ if (!success) { /* The Command itself failed */ if (bson_empty0(&writeresult->write_result.writeErrors) && bson_empty0(&writeresult->write_result.writeConcernErrors)) { /* FIXME: Maybe we can look at write_result.error and not pass error at all? */ phongo_throw_exception_from_bson_error_t(&error TSRMLS_CC); } else { char *bulk_error_msg; bulk_error_msg = phongo_assemble_bulk_write_error(&writeresult->write_result); phongo_throw_exception(PHONGO_ERROR_WRITE_FAILED TSRMLS_CC, "%s", bulk_error_msg); efree(bulk_error_msg); phongo_add_exception_prop(ZEND_STRL("writeResult"), return_value TSRMLS_CC); } return false; } return true; } /* }}} */ int phongo_execute_query(mongoc_client_t *client, const char *namespace, const php_phongo_query_t *query, const mongoc_read_prefs_t *read_preference, int server_id, zval *return_value, int return_value_used TSRMLS_DC) /* {{{ */ { const bson_t *doc = NULL; mongoc_cursor_t *cursor; char *dbname; char *collname; mongoc_collection_t *collection; if (!phongo_split_namespace(namespace, &dbname, &collname)) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "%s: %s", "Invalid namespace provided", namespace); return false; } collection = mongoc_client_get_collection(client, dbname, collname); efree(dbname); efree(collname); if (query->read_concern) { mongoc_collection_set_read_concern(collection, query->read_concern); } cursor = mongoc_collection_find(collection, query->flags, query->skip, query->limit, query->batch_size, query->query, query->selector, read_preference); mongoc_collection_destroy(collection); /* mongoc issues a warning we need to catch somehow */ if (!cursor) { phongo_throw_exception(PHONGO_ERROR_MONGOC_FAILED TSRMLS_CC, "%s", "FIXME: Couldn't create cursor..."); return false; } if (server_id > 0) { cursor->hint = server_id; } if (!mongoc_cursor_next(cursor, &doc)) { bson_error_t error; /* Check for connection related exceptions */ if (EG(exception)) { mongoc_cursor_destroy(cursor); return false; } /* Could simply be no docs, which is not an error */ if (mongoc_cursor_error(cursor, &error)) { phongo_throw_exception_from_bson_error_t(&error TSRMLS_CC); mongoc_cursor_destroy(cursor); return false; } } if (!return_value_used) { mongoc_cursor_destroy(cursor); return true; } phongo_cursor_init(return_value, cursor, client TSRMLS_CC); return true; } /* }}} */ int phongo_execute_command(mongoc_client_t *client, const char *db, const bson_t *command, const mongoc_read_prefs_t *read_preference, int server_id, zval *return_value, int return_value_used TSRMLS_DC) /* {{{ */ { mongoc_cursor_t *cursor; const bson_t *doc; bson_iter_t iter; bson_iter_t child; cursor = mongoc_client_command(client, db, MONGOC_QUERY_NONE, 0, 1, 0, command, NULL, read_preference); if (server_id > 0) { cursor->hint = server_id; } if (!mongoc_cursor_next(cursor, &doc)) { bson_error_t error; /* Check for connection related exceptions */ if (EG(exception)) { mongoc_cursor_destroy(cursor); return false; } if (mongoc_cursor_error(cursor, &error)) { mongoc_cursor_destroy(cursor); phongo_throw_exception_from_bson_error_t(&error TSRMLS_CC); return false; } } if (!return_value_used) { mongoc_cursor_destroy(cursor); return true; } /* This code is adapated from _mongoc_cursor_cursorid_prime(), but we avoid * advancing the cursor, since we are already positioned at the first result * after the error checking above. */ if (bson_iter_init_find(&iter, doc, "cursor") && BSON_ITER_HOLDS_DOCUMENT(&iter) && bson_iter_recurse(&iter, &child)) { mongoc_cursor_cursorid_t *cid; bson_t empty = BSON_INITIALIZER; _mongoc_cursor_cursorid_init(cursor, &empty); cursor->limit = 0; cid = cursor->iface_data; cid->in_batch = true; bson_destroy (&empty); while (bson_iter_next(&child)) { if (BSON_ITER_IS_KEY(&child, "id")) { cursor->rpc.reply.cursor_id = bson_iter_as_int64(&child); } else if (BSON_ITER_IS_KEY(&child, "ns")) { const char *ns; ns = bson_iter_utf8(&child, &cursor->nslen); bson_strncpy(cursor->ns, ns, sizeof cursor->ns); } else if (BSON_ITER_IS_KEY(&child, "firstBatch")) { if (BSON_ITER_HOLDS_ARRAY(&child) && bson_iter_recurse(&child, &cid->batch_iter)) { cid->in_batch = true; } } } cursor->is_command = false; /* The cursor's current element is the command's response document. * Advance once so that the cursor is positioned at the first document * within the command cursor's result set. */ mongoc_cursor_next(cursor, &doc); } phongo_cursor_init(return_value, cursor, client TSRMLS_CC); return true; } /* }}} */ /* }}} */ /* {{{ Stream vtable */ void phongo_stream_destroy(mongoc_stream_t *stream_wrap) /* {{{ */ { php_phongo_stream_socket *base_stream = (php_phongo_stream_socket *)stream_wrap; if (base_stream->stream) { MONGOC_DEBUG("Not destroying RSRC#%d", PHONGO_STREAM_ID(base_stream->stream)); } else { MONGOC_DEBUG("Wrapped stream already destroyed"); } /* * DON'T DO ANYTHING TO THE INTERNAL base_stream->stream * The stream should not be closed during normal dtor -- as we want it to * survive until next request. * We only clean it up on failure and (implicitly) MSHUTDOWN */ efree(base_stream); } /* }}} */ void phongo_stream_failed(mongoc_stream_t *stream_wrap) /* {{{ */ { php_phongo_stream_socket *base_stream = (php_phongo_stream_socket *)stream_wrap; if (base_stream->stream) { #if PHP_VERSION_ID < 70000 PHONGO_TSRMLS_FETCH_FROM_CTX(base_stream->tsrm_ls); #endif MONGOC_DEBUG("Destroying RSRC#%d", PHONGO_STREAM_ID(base_stream->stream)); php_stream_free(base_stream->stream, PHP_STREAM_FREE_CLOSE_PERSISTENT | PHP_STREAM_FREE_RSRC_DTOR); base_stream->stream = NULL; } efree(base_stream); } /* }}} */ int phongo_stream_close(mongoc_stream_t *stream_wrap) /* {{{ */ { php_phongo_stream_socket *base_stream = (php_phongo_stream_socket *)stream_wrap; MONGOC_DEBUG("Closing RSRC#%d", PHONGO_STREAM_ID(base_stream->stream)); if (base_stream->stream) { #if PHP_VERSION_ID < 70000 TSRMLS_FETCH_FROM_CTX(base_stream->tsrm_ls); #endif MONGOC_DEBUG("Destroying RSRC#%d", PHONGO_STREAM_ID(base_stream->stream)); php_stream_free(base_stream->stream, PHP_STREAM_FREE_CLOSE_PERSISTENT | PHP_STREAM_FREE_RSRC_DTOR); base_stream->stream = NULL; } return 0; } /* }}} */ void php_phongo_set_timeout(php_phongo_stream_socket *base_stream, int32_t timeout_msec) /* {{{ */ { struct timeval rtimeout = {0, 0}; PHONGO_TSRMLS_FETCH_FROM_CTX(base_stream->tsrm_ls); if (timeout_msec > 0) { rtimeout.tv_sec = timeout_msec / 1000; rtimeout.tv_usec = (timeout_msec % 1000) * 1000; } php_stream_set_option(base_stream->stream, PHP_STREAM_OPTION_READ_TIMEOUT, 0, &rtimeout); MONGOC_DEBUG("Setting timeout to: %d", timeout_msec); } /* }}} */ /* This is blatantr copy of _mongoc_stream_tls_writev * https://github.com/mongodb/mongo-c-driver/blob/4ebba3d84286df3867bad89358eb6ae956e62a59/src/mongoc/mongoc-stream-tls.c#L500 */ ssize_t phongo_stream_writev(mongoc_stream_t *stream, mongoc_iovec_t *iov, size_t iovcnt, int32_t timeout_msec) /* {{{ */ { char buf[PHONGO_STREAM_BUFFER_SIZE]; ssize_t ret = 0; ssize_t child_ret; size_t i; size_t iov_pos = 0; /* There's a bit of a dance to coalesce vectorized writes into * PHONGO_STREAM_BUFFER_SIZE'd writes to avoid lots of small tls * packets. * * The basic idea is that we want to combine writes in the buffer if they're * smaller than the buffer, flushing as it gets full. For larger writes, or * the last write in the iovec array, we want to ignore the buffer and just * write immediately. We take care of doing buffer writes by re-invoking * ourself with a single iovec_t, pointing at our stack buffer. */ char *buf_head = buf; char *buf_tail = buf; char *buf_end = buf + PHONGO_STREAM_BUFFER_SIZE; size_t bytes; char *to_write = NULL; size_t to_write_len; php_phongo_stream_socket *base_stream = (php_phongo_stream_socket *)stream; PHONGO_TSRMLS_FETCH_FROM_CTX(base_stream->tsrm_ls); php_phongo_set_timeout(base_stream, timeout_msec); BSON_ASSERT (iov); BSON_ASSERT (iovcnt); for (i = 0; i < iovcnt; i++) { iov_pos = 0; while (iov_pos < iov[i].iov_len) { if (buf_head != buf_tail || ((i + 1 < iovcnt) && ((buf_end - buf_tail) > (iov[i].iov_len - iov_pos)))) { /* If we have either of: * - buffered bytes already * - another iovec to send after this one and we don't have more * bytes to send than the size of the buffer. * * copy into the buffer */ bytes = BSON_MIN (iov[i].iov_len - iov_pos, buf_end - buf_tail); memcpy (buf_tail, iov[i].iov_base + iov_pos, bytes); buf_tail += bytes; iov_pos += bytes; if (buf_tail == buf_end) { /* If we're full, request send */ to_write = buf_head; to_write_len = buf_tail - buf_head; buf_tail = buf_head = buf; } } else { /* Didn't buffer, so just write it through */ to_write = (char *)iov[i].iov_base + iov_pos; to_write_len = iov[i].iov_len - iov_pos; iov_pos += to_write_len; } if (to_write) { /* We get here if we buffered some bytes and filled the buffer, or * if we didn't buffer and have to send out of the iovec */ child_ret = php_stream_write(base_stream->stream, to_write, to_write_len); if (child_ret < 0) { /* Buffer write failed, just return the error */ return child_ret; } ret += child_ret; if (child_ret < to_write_len) { /* we timed out, so send back what we could send */ return ret; } to_write = NULL; } } } if (buf_head != buf_tail) { /* If we have any bytes buffered, send */ child_ret = php_stream_write(base_stream->stream, buf_head, buf_tail - buf_head); if (child_ret < 0) { return child_ret; } ret += child_ret; } return ret; } /* }}} */ ssize_t phongo_stream_readv(mongoc_stream_t *stream, mongoc_iovec_t *iov, size_t iovcnt, size_t min_bytes, int32_t timeout_msec) /* {{{ */ { php_phongo_stream_socket *base_stream = (php_phongo_stream_socket *)stream; ssize_t ret = 0; ssize_t read; size_t cur = 0; PHONGO_TSRMLS_FETCH_FROM_CTX(base_stream->tsrm_ls); php_phongo_set_timeout(base_stream, timeout_msec); do { read = php_stream_read(base_stream->stream, iov[cur].iov_base, iov[cur].iov_len); MONGOC_DEBUG("Reading got: %zd wanted: %zd", read, min_bytes); if (read <= 0) { if (ret >= (ssize_t)min_bytes) { break; } return -1; } ret += read; while ((cur < iovcnt) && (read >= (ssize_t)iov[cur].iov_len)) { read -= iov[cur++].iov_len; } if (cur == iovcnt) { break; } if (ret >= (ssize_t)min_bytes) { break; } iov[cur].iov_base = ((char *)iov[cur].iov_base) + read; iov[cur].iov_len -= read; } while(1); return ret; } /* }}} */ int phongo_stream_setsockopt(mongoc_stream_t *stream, int level, int optname, void *optval, socklen_t optlen) /* {{{ */ { php_phongo_stream_socket *base_stream = (php_phongo_stream_socket *)stream; int socket = ((php_netstream_data_t *)base_stream->stream->abstract)->socket; return setsockopt (socket, level, optname, optval, optlen); } /* }}} */ bool phongo_stream_socket_check_closed(mongoc_stream_t *stream) /* {{{ */ { php_phongo_stream_socket *base_stream = (php_phongo_stream_socket *)stream; PHONGO_TSRMLS_FETCH_FROM_CTX(base_stream->tsrm_ls); return PHP_STREAM_OPTION_RETURN_OK != php_stream_set_option(base_stream->stream, PHP_STREAM_OPTION_CHECK_LIVENESS, 0, NULL); } /* }}} */ ssize_t phongo_stream_poll (mongoc_stream_poll_t *streams, size_t nstreams, int32_t timeout) /* {{{ */ { php_pollfd *fds = NULL; size_t i; ssize_t rval = -1; TSRMLS_FETCH(); fds = emalloc(sizeof(*fds) * nstreams); for (i = 0; i < nstreams; i++) { php_socket_t this_fd; if (php_stream_cast(((php_phongo_stream_socket *)streams[i].stream)->stream, PHP_STREAM_AS_FD_FOR_SELECT | PHP_STREAM_CAST_INTERNAL, (void*)&this_fd, 0) == SUCCESS && this_fd >= 0) { fds[i].fd = this_fd; fds[i].events = streams[i].events; fds[i].revents = 0; } } rval = php_poll2(fds, nstreams, timeout); if (rval > 0) { for (i = 0; i < nstreams; i++) { streams[i].revents = fds[i].revents; } } efree(fds); return rval; } /* }}} */ #if PHP_VERSION_ID < 50600 int php_mongo_verify_hostname(const char *hostname, X509 *cert TSRMLS_DC) { if (php_mongo_matches_san_list(cert, hostname) == SUCCESS) { return SUCCESS; } if (php_mongo_matches_common_name(cert, hostname TSRMLS_CC) == SUCCESS) { return SUCCESS; } return FAILURE; } int php_phongo_peer_verify(php_stream *stream, X509 *cert, const char *hostname, bson_error_t *error TSRMLS_DC) { zval **verify_peer_name; /* This option is available since PHP 5.6.0 */ if (php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), "ssl", "verify_peer_name", &verify_peer_name) == SUCCESS && zend_is_true(*verify_peer_name)) { zval **zhost = NULL; const char *peer; if (php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), "ssl", "peer_name", &zhost) == SUCCESS) { convert_to_string_ex(zhost); peer = Z_STRVAL_PP(zhost); } else { peer = hostname; } if (php_mongo_verify_hostname(peer, cert TSRMLS_CC) == FAILURE) { bson_set_error(error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_CONNECT, "Remote certificate SubjectAltName or CN does not match '%s'", hostname); return false; } } return true; } #endif bool php_phongo_ssl_verify(php_stream *stream, const char *hostname, bson_error_t *error TSRMLS_DC) { #if PHP_VERSION_ID >= 70000 zval *zcert; zval *verify_expiry; #else zval **zcert; zval **verify_expiry; #endif X509 *cert; if (!PHP_STREAM_CONTEXT(stream)) { return true; } #if PHP_VERSION_ID >= 70000 if (!((zcert = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), "ssl", "peer_certificate")) != NULL && Z_TYPE_P(zcert) == IS_RESOURCE)) { #else if (!(php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), "ssl", "peer_certificate", &zcert) == SUCCESS && Z_TYPE_PP(zcert) == IS_RESOURCE)) { #endif bson_set_error(error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_CONNECT, "Could not capture certificate of %s", hostname); return false; } #if PHP_VERSION_ID >= 70000 cert = (X509 *)x509_from_zval(zcert TSRMLS_CC); #else cert = (X509 *)x509_from_zval(*zcert TSRMLS_CC); #endif if (!cert) { bson_set_error(error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_CONNECT, "Could not get certificate of %s", hostname); return false; } #if PHP_VERSION_ID < 50600 if (!php_phongo_peer_verify(stream, cert, hostname, error TSRMLS_CC)) { return false; } #endif #if PHP_VERSION_ID >= 70000 if ((verify_expiry = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), "ssl", "verify_expiry")) != NULL && zend_is_true(verify_expiry)) { #else if (php_stream_context_get_option(PHP_STREAM_CONTEXT(stream), "ssl", "verify_expiry", &verify_expiry) == SUCCESS && zend_is_true(*verify_expiry)) { #endif time_t current = time(NULL); time_t valid_from = php_mongo_asn1_time_to_time_t(X509_get_notBefore(cert) TSRMLS_CC); time_t valid_until = php_mongo_asn1_time_to_time_t(X509_get_notAfter(cert) TSRMLS_CC); if (valid_from > current) { bson_set_error(error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_CONNECT, "Certificate is not valid yet on %s", hostname); return false; } if (current > valid_until) { bson_set_error(error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_CONNECT, "Certificate has expired on %s", hostname); return false; } } return true; } mongoc_stream_t* phongo_stream_initiator(const mongoc_uri_t *uri, const mongoc_host_list_t *host, void *user_data, bson_error_t *error) /* {{{ */ { zend_error_handling error_handling; php_phongo_stream_socket *base_stream = NULL; php_stream *stream = NULL; const bson_t *options; bson_iter_t iter; struct timeval timeout = {0, 0}; struct timeval *timeoutp = NULL; char *uniqid; phongo_char *errmsg = NULL; int errcode; char *dsn; int dsn_len; TSRMLS_FETCH(); ENTRY; switch (host->family) { #if defined(AF_INET6) case AF_INET6: dsn_len = spprintf(&dsn, 0, "tcp://[%s]:%d", host->host, host->port); break; #endif case AF_INET: dsn_len = spprintf(&dsn, 0, "tcp://%s:%d", host->host, host->port); break; case AF_UNIX: dsn_len = spprintf(&dsn, 0, "unix://%s", host->host); break; default: bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_INVALID_TYPE, "Invalid address family: 0x%02x", host->family); RETURN(NULL); } options = mongoc_uri_get_options(uri); if (bson_iter_init_find (&iter, options, "connecttimeoutms") && BSON_ITER_HOLDS_INT32 (&iter)) { int32_t connecttimeoutms = MONGOC_DEFAULT_CONNECTTIMEOUTMS; if (!(connecttimeoutms = bson_iter_int32(&iter))) { connecttimeoutms = MONGOC_DEFAULT_CONNECTTIMEOUTMS; } timeout.tv_sec = connecttimeoutms / 1000; timeout.tv_usec = (connecttimeoutms % 1000) * 1000; timeoutp = &timeout; } spprintf(&uniqid, 0, "%s:%d[%s]", host->host, host->port, mongoc_uri_get_string(uri)); MONGOC_DEBUG("Connecting to '%s'", uniqid); zend_replace_error_handling(EH_SUPPRESS, NULL, &error_handling TSRMLS_CC); stream = php_stream_xport_create(dsn, dsn_len, 0, STREAM_XPORT_CLIENT | STREAM_XPORT_CONNECT, uniqid, timeoutp, (php_stream_context *)user_data, &errmsg, &errcode); zend_restore_error_handling(&error_handling TSRMLS_CC); if (!stream) { bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_CONNECT, "Failed connecting to '%s:%d': %s", host->host, host->port, phongo_str(errmsg)); efree(dsn); efree(uniqid); if (errmsg) { phongo_char_free(errmsg); } RETURN(NULL); } php_stream_auto_cleanup(stream); MONGOC_DEBUG("Created: RSRC#%d as '%s'", PHONGO_STREAM_ID(stream), uniqid); efree(uniqid); if (mongoc_uri_get_ssl(uri)) { zend_replace_error_handling(EH_THROW, php_phongo_sslconnectionexception_ce, &error_handling TSRMLS_CC); MONGOC_DEBUG("Enabling SSL"); /* Capture the server certificate so we can do further verification */ if (PHP_STREAM_CONTEXT(stream)) { zval capture; ZVAL_BOOL(&capture, 1); php_stream_context_set_option(PHP_STREAM_CONTEXT(stream), "ssl", "capture_peer_cert", &capture); } if (php_stream_xport_crypto_setup(stream, PHONGO_CRYPTO_METHOD, NULL TSRMLS_CC) < 0) { zend_restore_error_handling(&error_handling TSRMLS_CC); php_stream_free(stream, PHP_STREAM_FREE_CLOSE_PERSISTENT | PHP_STREAM_FREE_RSRC_DTOR); bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_INVALID_TYPE, "Failed to setup crypto, is the OpenSSL extension loaded?"); efree(dsn); return NULL; } if (php_stream_xport_crypto_enable(stream, 1 TSRMLS_CC) < 0) { zend_restore_error_handling(&error_handling TSRMLS_CC); php_stream_free(stream, PHP_STREAM_FREE_CLOSE_PERSISTENT | PHP_STREAM_FREE_RSRC_DTOR); bson_set_error (error, MONGOC_ERROR_STREAM, MONGOC_ERROR_STREAM_INVALID_TYPE, "Failed to setup crypto, is the server running with SSL?"); efree(dsn); return NULL; } if (!php_phongo_ssl_verify(stream, host->host, error TSRMLS_CC)) { zend_restore_error_handling(&error_handling TSRMLS_CC); php_stream_pclose(stream); efree(dsn); return NULL; } zend_restore_error_handling(&error_handling TSRMLS_CC); } efree(dsn); /* We only need the context really for SSL initialization, safe to remove now */ php_stream_context_set(stream, NULL); base_stream = ecalloc(1, sizeof(php_phongo_stream_socket)); base_stream->stream = stream; base_stream->uri = uri; base_stream->host = host; TSRMLS_SET_CTX(base_stream->tsrm_ls); /* flush missing, doesn't seem to be used */ base_stream->vtable.type = 100; base_stream->vtable.destroy = phongo_stream_destroy; base_stream->vtable.failed = phongo_stream_failed; base_stream->vtable.close = phongo_stream_close; base_stream->vtable.writev = phongo_stream_writev; base_stream->vtable.readv = phongo_stream_readv; base_stream->vtable.setsockopt = phongo_stream_setsockopt; base_stream->vtable.check_closed = phongo_stream_socket_check_closed; base_stream->vtable.poll = phongo_stream_poll; if (host->family != AF_UNIX) { int flag = 1; if (phongo_stream_setsockopt((mongoc_stream_t *)base_stream, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int))) { MONGOC_WARNING("setsockopt TCP_NODELAY failed"); } } RETURN((mongoc_stream_t *)base_stream); } /* }}} */ /* }}} */ /* {{{ mongoc types from from_zval */ const mongoc_write_concern_t* phongo_write_concern_from_zval(zval *zwrite_concern TSRMLS_DC) /* {{{ */ { if (zwrite_concern) { php_phongo_writeconcern_t *intern = Z_WRITECONCERN_OBJ_P(zwrite_concern); if (intern) { return intern->write_concern; } } return NULL; } /* }}} */ const mongoc_read_concern_t* phongo_read_concern_from_zval(zval *zread_concern TSRMLS_DC) /* {{{ */ { if (zread_concern) { php_phongo_readconcern_t *intern = Z_READCONCERN_OBJ_P(zread_concern); if (intern) { return intern->read_concern; } } return NULL; } /* }}} */ const mongoc_read_prefs_t* phongo_read_preference_from_zval(zval *zread_preference TSRMLS_DC) /* {{{ */ { if (zread_preference) { php_phongo_readpreference_t *intern = Z_READPREFERENCE_OBJ_P(zread_preference); if (intern) { return intern->read_preference; } } return NULL; } /* }}} */ const php_phongo_query_t* phongo_query_from_zval(zval *zquery TSRMLS_DC) /* {{{ */ { php_phongo_query_t *intern = Z_QUERY_OBJ_P(zquery); return intern; } /* }}} */ /* }}} */ /* {{{ phongo zval from mongoc types */ void php_phongo_cursor_id_new_from_id(zval *object, int64_t cursorid TSRMLS_DC) /* {{{ */ { php_phongo_cursorid_t *intern; object_init_ex(object, php_phongo_cursorid_ce); intern = Z_CURSORID_OBJ_P(object); intern->id = cursorid; } /* }}} */ void php_phongo_objectid_new_from_oid(zval *object, const bson_oid_t *oid TSRMLS_DC) /* {{{ */ { php_phongo_objectid_t *intern; object_init_ex(object, php_phongo_objectid_ce); intern = Z_OBJECTID_OBJ_P(object); bson_oid_to_string(oid, intern->oid); } /* }}} */ void php_phongo_server_to_zval(zval *retval, const mongoc_server_description_t *sd) /* {{{ */ { array_init(retval); ADD_ASSOC_STRING(retval, "host", (char *)sd->host.host); ADD_ASSOC_LONG_EX(retval, "port", sd->host.port); ADD_ASSOC_LONG_EX(retval, "type", sd->type); ADD_ASSOC_BOOL_EX(retval, "is_primary", sd->type == MONGOC_SERVER_RS_PRIMARY); ADD_ASSOC_BOOL_EX(retval, "is_secondary", sd->type == MONGOC_SERVER_RS_SECONDARY); ADD_ASSOC_BOOL_EX(retval, "is_arbiter", sd->type == MONGOC_SERVER_RS_ARBITER); { bson_iter_t iter; zend_bool b = bson_iter_init_find_case(&iter, &sd->last_is_master, "hidden") && bson_iter_as_bool(&iter); ADD_ASSOC_BOOL_EX(retval, "is_hidden", b); } { bson_iter_t iter; zend_bool b = bson_iter_init_find_case(&iter, &sd->last_is_master, "passive") && bson_iter_as_bool(&iter); ADD_ASSOC_BOOL_EX(retval, "is_passive", b); } if (sd->tags.len) { php_phongo_bson_state state = PHONGO_BSON_STATE_INITIALIZER; /* Use native arrays for debugging output */ state.map.root_type = PHONGO_TYPEMAP_NATIVE_ARRAY; state.map.document_type = PHONGO_TYPEMAP_NATIVE_ARRAY; phongo_bson_to_zval_ex(bson_get_data(&sd->tags), sd->tags.len, &state); #if PHP_VERSION_ID >= 70000 ADD_ASSOC_ZVAL_EX(retval, "tags", &state.zchild); #else ADD_ASSOC_ZVAL_EX(retval, "tags", state.zchild); #endif } { php_phongo_bson_state state = PHONGO_BSON_STATE_INITIALIZER; /* Use native arrays for debugging output */ state.map.root_type = PHONGO_TYPEMAP_NATIVE_ARRAY; state.map.document_type = PHONGO_TYPEMAP_NATIVE_ARRAY; phongo_bson_to_zval_ex(bson_get_data(&sd->last_is_master), sd->last_is_master.len, &state); #if PHP_VERSION_ID >= 70000 ADD_ASSOC_ZVAL_EX(retval, "last_is_master", &state.zchild); #else ADD_ASSOC_ZVAL_EX(retval, "last_is_master", state.zchild); #endif } ADD_ASSOC_LONG_EX(retval, "round_trip_time", sd->round_trip_time); } /* }}} */ void php_phongo_read_concern_to_zval(zval *retval, const mongoc_read_concern_t *read_concern) /* {{{ */ { const char *level = mongoc_read_concern_get_level(read_concern); array_init_size(retval, 1); if (level) { ADD_ASSOC_STRING(retval, "level", (char *)level); } else { ADD_ASSOC_NULL_EX(retval, "level"); } } /* }}} */ void php_phongo_read_preference_to_zval(zval *retval, const mongoc_read_prefs_t *read_prefs) /* {{{ */ { array_init_size(retval, 2); ADD_ASSOC_LONG_EX(retval, "mode", read_prefs->mode); if (read_prefs->tags.len) { php_phongo_bson_state state = PHONGO_BSON_STATE_INITIALIZER; /* Use native arrays for debugging output */ state.map.root_type = PHONGO_TYPEMAP_NATIVE_ARRAY; state.map.document_type = PHONGO_TYPEMAP_NATIVE_ARRAY; phongo_bson_to_zval_ex(bson_get_data(&read_prefs->tags), read_prefs->tags.len, &state); #if PHP_VERSION_ID >= 70000 ADD_ASSOC_ZVAL_EX(retval, "tags", &state.zchild); #else ADD_ASSOC_ZVAL_EX(retval, "tags", state.zchild); #endif } else { ADD_ASSOC_NULL_EX(retval, "tags"); } } /* }}} */ void php_phongo_write_concern_to_zval(zval *retval, const mongoc_write_concern_t *write_concern) /* {{{ */ { const char *wtag = mongoc_write_concern_get_wtag(write_concern); const int32_t w = mongoc_write_concern_get_w(write_concern); array_init_size(retval, 4); if (wtag) { ADD_ASSOC_STRING(retval, "w", (char *)wtag); } else if (mongoc_write_concern_get_wmajority(write_concern)) { ADD_ASSOC_STRING(retval, "w", (char *)PHONGO_WRITE_CONCERN_W_MAJORITY); } else if (w != MONGOC_WRITE_CONCERN_W_DEFAULT) { ADD_ASSOC_LONG_EX(retval, "w", w); } else { ADD_ASSOC_NULL_EX(retval, "w"); } ADD_ASSOC_BOOL_EX(retval, "wmajority", mongoc_write_concern_get_wmajority(write_concern)); ADD_ASSOC_LONG_EX(retval, "wtimeout", mongoc_write_concern_get_wtimeout(write_concern)); if (write_concern->journal != MONGOC_WRITE_CONCERN_JOURNAL_DEFAULT) { ADD_ASSOC_BOOL_EX(retval, "journal", mongoc_write_concern_get_journal(write_concern)); } else { ADD_ASSOC_NULL_EX(retval, "journal"); } } /* }}} */ void php_phongo_cursor_to_zval(zval *retval, const mongoc_cursor_t *cursor) /* {{{ */ { array_init_size(retval, 19); ADD_ASSOC_LONG_EX(retval, "stamp", cursor->stamp); #define _ADD_BOOL(z, field) ADD_ASSOC_BOOL_EX(z, #field, cursor->field) _ADD_BOOL(retval, is_command); _ADD_BOOL(retval, sent); _ADD_BOOL(retval, done); _ADD_BOOL(retval, end_of_event); _ADD_BOOL(retval, in_exhaust); _ADD_BOOL(retval, has_fields); #undef _ADD_BOOL /* Avoid using PHONGO_TYPEMAP_NATIVE_ARRAY for decoding query, selector, * and current documents so that users can differentiate BSON arrays * and documents. */ { #if PHP_VERSION_ID >= 70000 zval zv; #else zval *zv; #endif phongo_bson_to_zval(bson_get_data(&cursor->query), cursor->query.len, &zv); #if PHP_VERSION_ID >= 70000 ADD_ASSOC_ZVAL_EX(retval, "query", &zv); #else ADD_ASSOC_ZVAL_EX(retval, "query", zv); #endif } { #if PHP_VERSION_ID >= 70000 zval zv; #else zval *zv; #endif phongo_bson_to_zval(bson_get_data(&cursor->fields), cursor->fields.len, &zv); #if PHP_VERSION_ID >= 70000 ADD_ASSOC_ZVAL_EX(retval, "fields", &zv); #else ADD_ASSOC_ZVAL_EX(retval, "fields", zv); #endif } { #if PHP_VERSION_ID >= 70000 zval read_preference; php_phongo_read_preference_to_zval(&read_preference, cursor->read_prefs); ADD_ASSOC_ZVAL_EX(retval, "read_preference", &read_preference); #else zval *read_preference = NULL; MAKE_STD_ZVAL(read_preference); php_phongo_read_preference_to_zval(read_preference, cursor->read_prefs); ADD_ASSOC_ZVAL_EX(retval, "read_preference", read_preference); #endif } #define _ADD_INT(z, field) ADD_ASSOC_LONG_EX(z, #field, cursor->field) _ADD_INT(retval, flags); _ADD_INT(retval, skip); _ADD_INT(retval, limit); _ADD_INT(retval, count); _ADD_INT(retval, batch_size); #undef _ADD_INT ADD_ASSOC_STRING(retval, "ns", (char *)cursor->ns); if (cursor->current) { #if PHP_VERSION_ID >= 70000 zval zv; #else zval *zv; #endif phongo_bson_to_zval(bson_get_data(cursor->current), cursor->current->len, &zv); #if PHP_VERSION_ID >= 70000 ADD_ASSOC_ZVAL_EX(retval, "current_doc", &zv); #else ADD_ASSOC_ZVAL_EX(retval, "current_doc", zv); #endif } } /* }}} */ /* }}} */ static mongoc_uri_t *php_phongo_make_uri(const char *uri_string, bson_t *options) /* {{{ */ { bson_iter_t iter; mongoc_uri_t *uri; uri = mongoc_uri_new(uri_string); MONGOC_DEBUG("Connection string: '%s'", uri_string); if (!uri) { return NULL; } if (options && bson_iter_init(&iter, options)) { while (bson_iter_next (&iter)) { const char *key = bson_iter_key(&iter); /* Skip read preference and write concern options, as those must be * processed after the mongoc_client_t is constructed. */ if (!strcasecmp(key, "journal") || !strcasecmp(key, "readpreference") || !strcasecmp(key, "readpreferencetags") || !strcasecmp(key, "safe") || !strcasecmp(key, "slaveok") || !strcasecmp(key, "w") || !strcasecmp(key, "wtimeoutms")) { continue; } if (mongoc_uri_option_is_bool(key)) { mongoc_uri_set_option_as_bool (uri, key, bson_iter_as_bool(&iter)); } else if (mongoc_uri_option_is_int32(key) && BSON_ITER_HOLDS_INT32(&iter)) { mongoc_uri_set_option_as_int32 (uri, key, bson_iter_int32 (&iter)); } else if (mongoc_uri_option_is_utf8(key) && BSON_ITER_HOLDS_UTF8(&iter)) { mongoc_uri_set_option_as_utf8(uri, key, bson_iter_utf8 (&iter, NULL)); } else if (BSON_ITER_HOLDS_UTF8(&iter)) { const char *value = bson_iter_utf8 (&iter, NULL); if (!strcasecmp(key, "username")) { mongoc_uri_set_username(uri, value); } else if (!strcasecmp(key, "password")) { mongoc_uri_set_password(uri, value); } else if (!strcasecmp(key, "database")) { mongoc_uri_set_database(uri, value); } else if (!strcasecmp(key, "authsource")) { mongoc_uri_set_auth_source(uri, value); } } } } return uri; } /* }}} */ void php_phongo_populate_default_ssl_ctx(php_stream_context *ctx, zval *driverOptions) /* {{{ */ { #if PHP_VERSION_ID >= 70000 zval *tmp; #define SET_STRING_CTX(name) \ if (driverOptions && php_array_exists(driverOptions, name)) { \ zval ztmp; \ zend_bool ctmp_free; \ int ctmp_len; \ char *ctmp; \ ctmp = php_array_fetchl_string(driverOptions, name, sizeof(name)-1, &ctmp_len, &ctmp_free); \ ZVAL_STRING(&ztmp, ctmp); \ if (ctmp_free) { \ str_efree(ctmp); \ } \ php_stream_context_set_option(ctx, "ssl", name, &ztmp); \ zval_ptr_dtor(&ztmp); \ } #define SET_BOOL_CTX(name, defaultvalue) \ { \ zval ztmp; \ if (driverOptions && php_array_exists(driverOptions, name)) { \ ZVAL_BOOL(&ztmp, php_array_fetchl_bool(driverOptions, ZEND_STRL(name))); \ php_stream_context_set_option(ctx, "ssl", name, &ztmp); \ } \ else if ((tmp = php_stream_context_get_option(ctx, "ssl", name)) == NULL) { \ ZVAL_BOOL(&ztmp, defaultvalue); \ php_stream_context_set_option(ctx, "ssl", name, &ztmp); \ } \ } #else zval **tmp; #define SET_STRING_CTX(name) \ if (driverOptions && php_array_exists(driverOptions, name)) { \ zval ztmp; \ zend_bool ctmp_free; \ int ctmp_len; \ char *ctmp; \ ctmp = php_array_fetchl_string(driverOptions, name, sizeof(name)-1, &ctmp_len, &ctmp_free); \ ZVAL_STRING(&ztmp, ctmp, ctmp_free); \ php_stream_context_set_option(ctx, "ssl", name, &ztmp); \ } #define SET_BOOL_CTX(name, defaultvalue) \ { \ zval ztmp; \ if (driverOptions && php_array_exists(driverOptions, name)) { \ ZVAL_BOOL(&ztmp, php_array_fetchl_bool(driverOptions, ZEND_STRL(name))); \ php_stream_context_set_option(ctx, "ssl", name, &ztmp); \ } \ else if (php_stream_context_get_option(ctx, "ssl", name, &tmp) == FAILURE) { \ ZVAL_BOOL(&ztmp, defaultvalue); \ php_stream_context_set_option(ctx, "ssl", name, &ztmp); \ } \ } #endif SET_BOOL_CTX("verify_peer", 1); SET_BOOL_CTX("verify_peer_name", 1); SET_BOOL_CTX("verify_hostname", 1); SET_BOOL_CTX("verify_expiry", 1); SET_BOOL_CTX("allow_self_signed", 0); SET_STRING_CTX("peer_name"); SET_STRING_CTX("local_pk"); SET_STRING_CTX("local_cert"); SET_STRING_CTX("cafile"); SET_STRING_CTX("capath"); SET_STRING_CTX("passphrase"); SET_STRING_CTX("ciphers"); #undef SET_BOOL_CTX #undef SET_STRING_CTX } /* }}} */ static bool php_phongo_apply_rc_options_to_client(mongoc_client_t *client, bson_t *options TSRMLS_DC) /* {{{ */ { bson_iter_t iter; mongoc_read_concern_t *new_rc; const mongoc_read_concern_t *old_rc; if (!(old_rc = mongoc_client_get_read_concern(client))) { phongo_throw_exception(PHONGO_ERROR_MONGOC_FAILED TSRMLS_CC, "Client does not have a read concern"); return false; } /* Return early if there are no options to apply */ if (bson_empty0(options)) { return true; } if (!bson_iter_init_find_case(&iter, options, "readconcernlevel")) { return true; } new_rc = mongoc_read_concern_copy(old_rc); if (bson_iter_init_find_case(&iter, options, "readconcernlevel") && BSON_ITER_HOLDS_UTF8(&iter)) { const char *str = bson_iter_utf8(&iter, NULL); mongoc_read_concern_set_level(new_rc, str); } mongoc_client_set_read_concern(client, new_rc); mongoc_read_concern_destroy(new_rc); return true; } /* }}} */ static bool php_phongo_apply_rp_options_to_client(mongoc_client_t *client, bson_t *options TSRMLS_DC) /* {{{ */ { bson_iter_t iter; mongoc_read_prefs_t *new_rp; const mongoc_read_prefs_t *old_rp; if (!(old_rp = mongoc_client_get_read_prefs(client))) { phongo_throw_exception(PHONGO_ERROR_MONGOC_FAILED TSRMLS_CC, "Client does not have a read preference"); return false; } /* Return early if there are no options to apply */ if (bson_empty0(options)) { return true; } if (!bson_iter_init_find_case(&iter, options, "slaveok") && !bson_iter_init_find_case(&iter, options, "readpreference") && !bson_iter_init_find_case(&iter, options, "readpreferencetags")) { return true; } new_rp = mongoc_read_prefs_copy(old_rp); if (bson_iter_init_find_case(&iter, options, "slaveok") && BSON_ITER_HOLDS_BOOL(&iter)) { mongoc_read_prefs_set_mode(new_rp, MONGOC_READ_SECONDARY_PREFERRED); } if (bson_iter_init_find_case(&iter, options, "readpreference") && BSON_ITER_HOLDS_UTF8(&iter)) { const char *str = bson_iter_utf8(&iter, NULL); if (0 == strcasecmp("primary", str)) { mongoc_read_prefs_set_mode(new_rp, MONGOC_READ_PRIMARY); } else if (0 == strcasecmp("primarypreferred", str)) { mongoc_read_prefs_set_mode(new_rp, MONGOC_READ_PRIMARY_PREFERRED); } else if (0 == strcasecmp("secondary", str)) { mongoc_read_prefs_set_mode(new_rp, MONGOC_READ_SECONDARY); } else if (0 == strcasecmp("secondarypreferred", str)) { mongoc_read_prefs_set_mode(new_rp, MONGOC_READ_SECONDARY_PREFERRED); } else if (0 == strcasecmp("nearest", str)) { mongoc_read_prefs_set_mode(new_rp, MONGOC_READ_NEAREST); } else { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Unsupported readPreference value: '%s'", str); mongoc_read_prefs_destroy(new_rp); return false; } } if (bson_iter_init_find_case(&iter, options, "readpreferencetags") && BSON_ITER_HOLDS_ARRAY(&iter)) { bson_t tags; uint32_t len; const uint8_t *data; bson_iter_array(&iter, &len, &data); if (bson_init_static(&tags, data, len)) { mongoc_read_prefs_set_tags(new_rp, &tags); } } if (mongoc_read_prefs_get_mode(new_rp) == MONGOC_READ_PRIMARY && !bson_empty(mongoc_read_prefs_get_tags(new_rp))) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Primary read preference mode conflicts with tags"); mongoc_read_prefs_destroy(new_rp); return false; } /* This may be redundant in light of the last check (primary with tags), but * we'll check anyway in case additional validation is implemented. */ if (!mongoc_read_prefs_is_valid(new_rp)) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Read preference is not valid"); mongoc_read_prefs_destroy(new_rp); return false; } mongoc_client_set_read_prefs(client, new_rp); mongoc_read_prefs_destroy(new_rp); return true; } /* }}} */ static bool php_phongo_apply_wc_options_to_client(mongoc_client_t *client, bson_t *options TSRMLS_DC) /* {{{ */ { bson_iter_t iter; int32_t wtimeoutms; mongoc_write_concern_t *new_wc; const mongoc_write_concern_t *old_wc; if (!(old_wc = mongoc_client_get_write_concern(client))) { phongo_throw_exception(PHONGO_ERROR_MONGOC_FAILED TSRMLS_CC, "Client does not have a write concern"); return false; } /* Return early if there are no options to apply */ if (bson_empty0(options)) { return true; } if (!bson_iter_init_find_case(&iter, options, "journal") && !bson_iter_init_find_case(&iter, options, "safe") && !bson_iter_init_find_case(&iter, options, "w") && !bson_iter_init_find_case(&iter, options, "wtimeoutms")) { return true; } wtimeoutms = mongoc_write_concern_get_wtimeout(old_wc); new_wc = mongoc_write_concern_copy(old_wc); if (bson_iter_init_find_case(&iter, options, "safe") && BSON_ITER_HOLDS_BOOL(&iter)) { mongoc_write_concern_set_w(new_wc, bson_iter_bool(&iter) ? 1 : MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED); } if (bson_iter_init_find_case(&iter, options, "wtimeoutms") && BSON_ITER_HOLDS_INT32(&iter)) { wtimeoutms = bson_iter_int32(&iter); } if (bson_iter_init_find_case(&iter, options, "journal") && BSON_ITER_HOLDS_BOOL(&iter)) { mongoc_write_concern_set_journal(new_wc, bson_iter_bool(&iter)); } if (bson_iter_init_find_case(&iter, options, "w")) { if (BSON_ITER_HOLDS_INT32(&iter)) { int32_t value = bson_iter_int32(&iter); switch (value) { case MONGOC_WRITE_CONCERN_W_ERRORS_IGNORED: case MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED: mongoc_write_concern_set_w(new_wc, value); break; default: if (value > 0) { mongoc_write_concern_set_w(new_wc, value); break; } phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Unsupported w value: %d", value); mongoc_write_concern_destroy(new_wc); return false; } } else if (BSON_ITER_HOLDS_UTF8(&iter)) { const char *str = bson_iter_utf8(&iter, NULL); if (0 == strcasecmp(PHONGO_WRITE_CONCERN_W_MAJORITY, str)) { mongoc_write_concern_set_wmajority(new_wc, wtimeoutms); } else { mongoc_write_concern_set_wtag(new_wc, str); } } } /* Only set wtimeout if it's still applicable; otherwise, clear it. */ if (mongoc_write_concern_get_w(new_wc) > 1 || mongoc_write_concern_get_wmajority(new_wc) || mongoc_write_concern_get_wtag(new_wc)) { mongoc_write_concern_set_wtimeout(new_wc, wtimeoutms); } else { mongoc_write_concern_set_wtimeout(new_wc, 0); } if (mongoc_write_concern_get_journal(new_wc)) { int32_t w = mongoc_write_concern_get_w(new_wc); if (w == MONGOC_WRITE_CONCERN_W_UNACKNOWLEDGED || w == MONGOC_WRITE_CONCERN_W_ERRORS_IGNORED) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Journal conflicts with w value: %d", w); mongoc_write_concern_destroy(new_wc); return false; } } /* This may be redundant in light of the last check (unacknowledged w with journal), but we'll check anyway in case additional validation is implemented. */ if (!_mongoc_write_concern_is_valid(new_wc)) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Write concern is not valid"); mongoc_write_concern_destroy(new_wc); return false; } mongoc_client_set_write_concern(client, new_wc); mongoc_write_concern_destroy(new_wc); return true; } /* }}} */ static mongoc_client_t *php_phongo_make_mongo_client(const mongoc_uri_t *uri, zval *driverOptions TSRMLS_DC) /* {{{ */ { #if PHP_VERSION_ID >= 70000 zval *tmp; #else zval **tmp; #endif php_stream_context *ctx = NULL; const char *mech, *mongoc_version, *bson_version; mongoc_client_t *client; ENTRY; #if PHP_VERSION_ID >= 70000 if (driverOptions && (tmp = zend_hash_str_find(Z_ARRVAL_P(driverOptions), "debug", sizeof("debug")-1)) != NULL) { zend_string *key = zend_string_init(PHONGO_DEBUG_INI, sizeof(PHONGO_DEBUG_INI)-1, 0); zend_string *value_str = zval_get_string(tmp); zend_alter_ini_entry_ex(key, value_str, PHP_INI_USER, PHP_INI_STAGE_RUNTIME, 0); zend_string_release(key); zend_string_release(value_str); } #else if (driverOptions && zend_hash_find(Z_ARRVAL_P(driverOptions), "debug", strlen("debug") + 1, (void**)&tmp) == SUCCESS) { convert_to_string(*tmp); zend_alter_ini_entry_ex((char *)PHONGO_DEBUG_INI, sizeof(PHONGO_DEBUG_INI), Z_STRVAL_PP(tmp), Z_STRLEN_PP(tmp), PHP_INI_USER, PHP_INI_STAGE_RUNTIME, 0 TSRMLS_CC); } #endif #if PHP_VERSION_ID >= 70000 if (driverOptions && (tmp = zend_hash_str_find(Z_ARRVAL_P(driverOptions), "context", sizeof("context")-1)) != NULL) { ctx = php_stream_context_from_zval(tmp, 0); #else if (driverOptions && zend_hash_find(Z_ARRVAL_P(driverOptions), "context", strlen("context") + 1, (void**)&tmp) == SUCCESS) { ctx = php_stream_context_from_zval(*tmp, 0); #endif } else { GET_DEFAULT_CONTEXT(); } if (mongoc_uri_get_ssl(uri)) { php_phongo_populate_default_ssl_ctx(ctx, driverOptions); } #ifdef HAVE_SYSTEM_LIBMONGOC mongoc_version = mongoc_get_version(); #else mongoc_version = "bundled"; #endif #ifdef HAVE_SYSTEM_LIBBSON bson_version = bson_get_version(); #else bson_version = "bundled"; #endif MONGOC_DEBUG("Creating Manager, phongo-%s[%s] - mongoc-%s(%s), libbson-%s(%s), php-%s", MONGODB_VERSION_S, MONGODB_STABILITY_S, MONGOC_VERSION_S, mongoc_version, BSON_VERSION_S, bson_version, PHP_VERSION ); client = mongoc_client_new_from_uri(uri); if (!client) { RETURN(NULL); } mech = mongoc_uri_get_auth_mechanism(uri); /* Check if we are doing X509 auth, in which case extract the username (subject) from the cert if no username is provided */ if (mech && !strcasecmp(mech, "MONGODB-X509") && !mongoc_uri_get_username(uri)) { #if PHP_VERSION_ID >= 70000 zval *pem; #else zval **pem; #endif #if PHP_VERSION_ID >= 70000 if ((pem = php_stream_context_get_option(ctx, "ssl", "local_cert")) != NULL) { #else if (SUCCESS == php_stream_context_get_option(ctx, "ssl", "local_cert", &pem)) { #endif char filename[MAXPATHLEN]; #if PHP_VERSION_ID >= 70000 zend_string *s = zval_get_string(pem); if (VCWD_REALPATH(ZSTR_VAL(s), filename)) { #else convert_to_string_ex(pem); if (VCWD_REALPATH(Z_STRVAL_PP(pem), filename)) { #endif mongoc_ssl_opt_t ssl_options; ssl_options.pem_file = filename; mongoc_client_set_ssl_opts(client, &ssl_options); } #if PHP_VERSION_ID >= 70000 zend_string_release(s); #endif } } mongoc_client_set_stream_initiator(client, phongo_stream_initiator, ctx); RETURN(client); } /* }}} */ bool phongo_manager_init(php_phongo_manager_t *manager, const char *uri_string, bson_t *bson_options, zval *driverOptions TSRMLS_DC) /* {{{ */ { mongoc_uri_t *uri; if (!(uri = php_phongo_make_uri(uri_string, bson_options))) { phongo_throw_exception(PHONGO_ERROR_INVALID_ARGUMENT TSRMLS_CC, "Failed to parse MongoDB URI: '%s'", uri_string); return false; } manager->client = php_phongo_make_mongo_client(uri, driverOptions TSRMLS_CC); mongoc_uri_destroy(uri); if (!manager->client) { phongo_throw_exception(PHONGO_ERROR_RUNTIME TSRMLS_CC, "Failed to create Manager from URI: '%s'", uri_string); return false; } if (!php_phongo_apply_rc_options_to_client(manager->client, bson_options TSRMLS_CC) || !php_phongo_apply_rp_options_to_client(manager->client, bson_options TSRMLS_CC) || !php_phongo_apply_wc_options_to_client(manager->client, bson_options TSRMLS_CC)) { /* Exception should already have been thrown */ return false; } return true; } /* }}} */ void php_phongo_new_utcdatetime_from_epoch(zval *object, int64_t msec_since_epoch TSRMLS_DC) /* {{{ */ { php_phongo_utcdatetime_t *intern; object_init_ex(object, php_phongo_utcdatetime_ce); intern = Z_UTCDATETIME_OBJ_P(object); intern->milliseconds = msec_since_epoch; } /* }}} */ void php_phongo_new_datetime_from_utcdatetime(zval *object, int64_t milliseconds TSRMLS_DC) /* {{{ */ { php_date_obj *datetime_obj; char *sec; int sec_len; object_init_ex(object, php_date_get_date_ce()); #ifdef WIN32 sec_len = spprintf(&sec, 0, "@%I64d", (int64_t) milliseconds / 1000); #else sec_len = spprintf(&sec, 0, "@%lld", (long long int) milliseconds / 1000); #endif datetime_obj = Z_PHPDATE_P(object); php_date_initialize(datetime_obj, sec, sec_len, NULL, NULL, 0 TSRMLS_CC); efree(sec); datetime_obj->time->f = milliseconds % 1000; } /* }}} */ void php_phongo_new_timestamp_from_increment_and_timestamp(zval *object, uint32_t increment, uint32_t timestamp TSRMLS_DC) /* {{{ */ { php_phongo_timestamp_t *intern; object_init_ex(object, php_phongo_timestamp_ce); intern = Z_TIMESTAMP_OBJ_P(object); intern->increment = increment; intern->timestamp = timestamp; } /* }}} */ void php_phongo_new_javascript_from_javascript(int init, zval *object, const char *code, size_t code_len TSRMLS_DC) /* {{{ */ { php_phongo_new_javascript_from_javascript_and_scope(init, object, code, code_len, NULL TSRMLS_CC); } /* }}} */ void php_phongo_new_javascript_from_javascript_and_scope(int init, zval *object, const char *code, size_t code_len, const bson_t *scope TSRMLS_DC) /* {{{ */ { php_phongo_javascript_t *intern; if (init) { object_init_ex(object, php_phongo_javascript_ce); } intern = Z_JAVASCRIPT_OBJ_P(object); intern->javascript = estrndup(code, code_len); intern->javascript_len = code_len; intern->document = scope ? bson_copy(scope) : NULL; } /* }}} */ void php_phongo_new_binary_from_binary_and_type(zval *object, const char *data, size_t data_len, bson_subtype_t type TSRMLS_DC) /* {{{ */ { php_phongo_binary_t *intern; object_init_ex(object, php_phongo_binary_ce); intern = Z_BINARY_OBJ_P(object); intern->data = estrndup(data, data_len); intern->data_len = data_len; intern->type = (uint8_t) type; } /* }}} */ void php_phongo_new_regex_from_regex_and_options(zval *object, const char *pattern, const char *flags TSRMLS_DC) /* {{{ */ { php_phongo_regex_t *intern; object_init_ex(object, php_phongo_regex_ce); intern = Z_REGEX_OBJ_P(object); intern->pattern_len = strlen(pattern); intern->pattern = estrndup(pattern, intern->pattern_len); intern->flags_len = strlen(flags); intern->flags = estrndup(flags, intern->flags_len); } /* }}} */ static void php_phongo_cursor_free_current(php_phongo_cursor_t *cursor) /* {{{ */ { if (!Z_ISUNDEF(cursor->visitor_data.zchild)) { zval_ptr_dtor(&cursor->visitor_data.zchild); #if PHP_VERSION_ID >= 70000 ZVAL_UNDEF(&cursor->visitor_data.zchild); #else cursor->visitor_data.zchild = NULL; #endif } } /* }}} */ void php_phongo_cursor_free(php_phongo_cursor_t *cursor) /* {{{ */ { if (cursor->cursor) { mongoc_cursor_destroy(cursor->cursor); cursor->cursor = NULL; } php_phongo_cursor_free_current(cursor); } /* }}} */ /* {{{ Iterator */ static void php_phongo_cursor_iterator_dtor(zend_object_iterator *iter TSRMLS_DC) /* {{{ */ { php_phongo_cursor_iterator *cursor_it = (php_phongo_cursor_iterator *)iter; if (!Z_ISUNDEF(cursor_it->intern.data)) { #if PHP_VERSION_ID >= 70000 zval_ptr_dtor(&cursor_it->intern.data); #else zval_ptr_dtor((zval**)&cursor_it->intern.data); cursor_it->intern.data = NULL; #endif } #if PHP_VERSION_ID < 70000 efree(cursor_it); #endif } /* }}} */ static int php_phongo_cursor_iterator_valid(zend_object_iterator *iter TSRMLS_DC) /* {{{ */ { php_phongo_cursor_t *cursor = ((php_phongo_cursor_iterator *)iter)->cursor; if (!Z_ISUNDEF(cursor->visitor_data.zchild)) { return SUCCESS; } return FAILURE; } /* }}} */ #if PHP_VERSION_ID < 50500 static int php_phongo_cursor_iterator_get_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC) /* {{{ */ { *int_key = (ulong) ((php_phongo_cursor_iterator *)iter)->current; return HASH_KEY_IS_LONG; } /* }}} */ #else static void php_phongo_cursor_iterator_get_current_key(zend_object_iterator *iter, zval *key TSRMLS_DC) /* {{{ */ { ZVAL_LONG(key, ((php_phongo_cursor_iterator *)iter)->current); } /* }}} */ #endif #if PHP_VERSION_ID < 70000 static void php_phongo_cursor_iterator_get_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC) /* {{{ */ { php_phongo_cursor_t *cursor = ((php_phongo_cursor_iterator *)iter)->cursor; *data = &cursor->visitor_data.zchild; } /* }}} */ #else static zval* php_phongo_cursor_iterator_get_current_data(zend_object_iterator *iter) /* {{{ */ { php_phongo_cursor_t *cursor = ((php_phongo_cursor_iterator *)iter)->cursor; return &cursor->visitor_data.zchild; } /* }}} */ #endif static void php_phongo_cursor_iterator_move_forward(zend_object_iterator *iter TSRMLS_DC) /* {{{ */ { php_phongo_cursor_iterator *cursor_it = (php_phongo_cursor_iterator *)iter; php_phongo_cursor_t *cursor = cursor_it->cursor; const bson_t *doc; php_phongo_cursor_free_current(cursor); cursor_it->current++; if (mongoc_cursor_next(cursor->cursor, &doc)) { phongo_bson_to_zval_ex(bson_get_data(doc), doc->len, &cursor->visitor_data); } else { bson_error_t error; if (mongoc_cursor_error(cursor->cursor, &error)) { /* Intentionally not destroying the cursor as it will happen * naturally now that there are no more results */ phongo_throw_exception_from_bson_error_t(&error TSRMLS_CC); } } } /* }}} */ static void php_phongo_cursor_iterator_rewind(zend_object_iterator *iter TSRMLS_DC) /* {{{ */ { php_phongo_cursor_iterator *cursor_it = (php_phongo_cursor_iterator *)iter; php_phongo_cursor_t *cursor = cursor_it->cursor; const bson_t *doc; if (cursor_it->current > 0) { phongo_throw_exception(PHONGO_ERROR_LOGIC TSRMLS_CC, "Cursors cannot rewind after starting iteration"); return; } php_phongo_cursor_free_current(cursor); doc = mongoc_cursor_current(cursor->cursor); if (doc) { phongo_bson_to_zval_ex(bson_get_data(doc), doc->len, &cursor->visitor_data); } } /* }}} */ /* iterator handler table */ zend_object_iterator_funcs php_phongo_cursor_iterator_funcs = { php_phongo_cursor_iterator_dtor, php_phongo_cursor_iterator_valid, php_phongo_cursor_iterator_get_current_data, php_phongo_cursor_iterator_get_current_key, php_phongo_cursor_iterator_move_forward, php_phongo_cursor_iterator_rewind, NULL /* invalidate_current is not used */ }; zend_object_iterator *php_phongo_cursor_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC) /* {{{ */ { php_phongo_cursor_iterator *cursor_it = NULL; php_phongo_cursor_t *cursor = Z_CURSOR_OBJ_P(object); if (by_ref) { zend_error(E_ERROR, "An iterator cannot be used with foreach by reference"); } if (cursor->got_iterator) { phongo_throw_exception(PHONGO_ERROR_LOGIC TSRMLS_CC, "Cursors cannot yield multiple iterators"); return NULL; } cursor->got_iterator = 1; cursor_it = ecalloc(1, sizeof(php_phongo_cursor_iterator)); #if PHP_VERSION_ID >= 70000 zend_iterator_init(&cursor_it->intern); #endif #if PHP_VERSION_ID >= 70000 ZVAL_COPY(&cursor_it->intern.data, object); #else Z_ADDREF_P(object); cursor_it->intern.data = (void*)object; #endif cursor_it->intern.funcs = &php_phongo_cursor_iterator_funcs; cursor_it->cursor = cursor; /* cursor_it->current should already be allocated to zero */ php_phongo_cursor_free_current(cursor_it->cursor); return &cursor_it->intern; } /* }}} */ /* }}} */ /* {{{ Memory allocation wrappers */ static void* php_phongo_malloc(size_t num_bytes) /* {{{ */ { return emalloc(num_bytes); } /* }}} */ static void* php_phongo_calloc(size_t num_members, size_t num_bytes) /* {{{ */ { return ecalloc(num_members, num_bytes); } /* }}} */ static void* php_phongo_realloc(void *mem, size_t num_bytes) { /* {{{ */ return erealloc(mem, num_bytes); } /* }}} */ static void php_phongo_free(void *mem) /* {{{ */ { if (mem) { efree(mem); } } /* }}} */ /* }}} */ #ifdef PHP_DEBUG /* LCOV_EXCL_START */ void _phongo_debug_bson(bson_t *bson) { char *str; size_t str_len; str = bson_as_json(bson, &str_len); php_printf("JSON: %s\n", str); bson_free(str); } /* LCOV_EXCL_STOP */ #endif /* {{{ M[INIT|SHUTDOWN] R[INIT|SHUTDOWN] G[INIT|SHUTDOWN] MINFO INI */ ZEND_INI_MH(OnUpdateDebug) { void ***ctx = NULL; char *tmp_dir = NULL; TSRMLS_SET_CTX(ctx); /* Close any previously open log files */ if (MONGODB_G(debug_fd)) { if (MONGODB_G(debug_fd) != stderr && MONGODB_G(debug_fd) != stdout) { fclose(MONGODB_G(debug_fd)); } MONGODB_G(debug_fd) = NULL; } if (!new_value || (new_value && !phongo_str(new_value)[0]) || strcasecmp("0", phongo_str(new_value)) == 0 || strcasecmp("off", phongo_str(new_value)) == 0 || strcasecmp("no", phongo_str(new_value)) == 0 || strcasecmp("false", phongo_str(new_value)) == 0 ) { mongoc_log_trace_disable(); mongoc_log_set_handler(NULL, NULL); #if PHP_VERSION_ID >= 70000 return OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC); #else return OnUpdateString(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC); #endif } if (strcasecmp(phongo_str(new_value), "stderr") == 0) { MONGODB_G(debug_fd) = stderr; } else if (strcasecmp(phongo_str(new_value), "stdout") == 0) { MONGODB_G(debug_fd) = stdout; } else if ( strcasecmp("1", phongo_str(new_value)) == 0 || strcasecmp("on", phongo_str(new_value)) == 0 || strcasecmp("yes", phongo_str(new_value)) == 0 || strcasecmp("true", phongo_str(new_value)) == 0 ) { tmp_dir = NULL; } else { tmp_dir = phongo_str(new_value); } if (!MONGODB_G(debug_fd)) { time_t t; int fd = -1; char *prefix; int len; phongo_char *filename; time(&t); len = spprintf(&prefix, 0, "PHONGO-%ld", t); fd = php_open_temporary_fd(tmp_dir, prefix, &filename TSRMLS_CC); if (fd != -1) { const char *path = phongo_str(filename); MONGODB_G(debug_fd) = VCWD_FOPEN(path, "a"); } efree(filename); efree(prefix); close(fd); } mongoc_log_trace_enable(); mongoc_log_set_handler(php_phongo_log, ctx); #if PHP_VERSION_ID >= 70000 return OnUpdateString(entry, new_value, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC); #else return OnUpdateString(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC); #endif } /* {{{ INI entries */ PHP_INI_BEGIN() #if PHP_VERSION_ID >= 70000 STD_PHP_INI_ENTRY(PHONGO_DEBUG_INI, PHONGO_DEBUG_INI_DEFAULT, PHP_INI_ALL, OnUpdateDebug, debug, zend_mongodb_globals, mongodb_globals) #else { 0, PHP_INI_ALL, (char *)PHONGO_DEBUG_INI, sizeof(PHONGO_DEBUG_INI), OnUpdateDebug, (void *) XtOffsetOf(zend_mongodb_globals, debug), (void *) &mglo, NULL, (char *)PHONGO_DEBUG_INI_DEFAULT, sizeof(PHONGO_DEBUG_INI_DEFAULT)-1, NULL, 0, 0, 0, NULL }, #endif PHP_INI_END() /* }}} */ /* {{{ PHP_GINIT_FUNCTION */ PHP_GINIT_FUNCTION(mongodb) { bson_mem_vtable_t bsonMemVTable = { php_phongo_malloc, php_phongo_calloc, php_phongo_realloc, php_phongo_free, }; #if PHP_VERSION_ID >= 70000 #if defined(COMPILE_DL_MONGODB) && defined(ZTS) ZEND_TSRMLS_CACHE_UPDATE(); #endif #endif mongodb_globals->debug_fd = NULL; mongodb_globals->bsonMemVTable = bsonMemVTable; } /* }}} */ /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(mongodb) { (void)type; /* We don't care if we are loaded via dl() or extension= */ REGISTER_INI_ENTRIES(); /* Initialize libmongoc */ mongoc_init(); /* Initialize libbson */ bson_mem_set_vtable(&MONGODB_G(bsonMemVTable)); /* Prep default object handlers to be used when we register the classes */ memcpy(&phongo_std_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); phongo_std_object_handlers.clone_obj = NULL; /* phongo_std_object_handlers.get_debug_info = NULL; phongo_std_object_handlers.compare_objects = NULL; phongo_std_object_handlers.cast_object = NULL; phongo_std_object_handlers.count_elements = NULL; phongo_std_object_handlers.get_closure = NULL; */ PHP_MINIT(bson)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(Command)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(Cursor)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(CursorId)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(Manager)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(Query)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(ReadConcern)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(ReadPreference)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(Server)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(BulkWrite)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(WriteConcern)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(WriteConcernError)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(WriteError)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(WriteResult)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(Exception)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(LogicException)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(RuntimeException)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(UnexpectedValueException)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(InvalidArgumentException)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(ConnectionException)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(AuthenticationException)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(SSLConnectionException)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(WriteException)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(BulkWriteException)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(ExecutionTimeoutException)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(ConnectionTimeoutException)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(Type)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(Serializable)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(Unserializable)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(Persistable)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(Binary)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(Javascript)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(MaxKey)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(MinKey)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(ObjectID)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(Regex)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(Timestamp)(INIT_FUNC_ARGS_PASSTHRU); PHP_MINIT(UTCDateTime)(INIT_FUNC_ARGS_PASSTHRU); REGISTER_STRING_CONSTANT("MONGODB_VERSION", (char *)MONGODB_VERSION_S, CONST_CS | CONST_PERSISTENT); REGISTER_STRING_CONSTANT("MONGODB_STABILITY", (char *)MONGODB_STABILITY_S, CONST_CS | CONST_PERSISTENT); REGISTER_STRING_CONSTANT("BSON_NAMESPACE", (char *)BSON_NAMESPACE, CONST_CS | CONST_PERSISTENT); return SUCCESS; } /* }}} */ /* {{{ PHP_MSHUTDOWN_FUNCTION */ PHP_MSHUTDOWN_FUNCTION(mongodb) { (void)type; /* We don't care if we are loaded via dl() or extension= */ bson_mem_restore_vtable(); /* Cleanup after libmongoc */ mongoc_cleanup(); UNREGISTER_INI_ENTRIES(); return SUCCESS; } /* }}} */ /* {{{ PHP_GSHUTDOWN_FUNCTION */ PHP_GSHUTDOWN_FUNCTION(mongodb) { mongodb_globals->debug = NULL; if (mongodb_globals->debug_fd) { fclose(mongodb_globals->debug_fd); mongodb_globals->debug_fd = NULL; } } /* }}} */ /* {{{ PHP_MINFO_FUNCTION */ PHP_MINFO_FUNCTION(mongodb) { php_info_print_table_start(); php_info_print_table_header(2, "mongodb support", "enabled"); php_info_print_table_row(2, "mongodb version", MONGODB_VERSION_S); php_info_print_table_row(2, "mongodb stability", MONGODB_STABILITY_S); #ifdef HAVE_SYSTEM_LIBMONGOC php_info_print_table_row(2, "libmongoc headers version", MONGOC_VERSION_S); php_info_print_table_row(2, "libmongoc library version", mongoc_get_version()); #else /* Bundled libraries, buildtime = runtime */ php_info_print_table_row(2, "libmongoc version", MONGOC_VERSION_S); #endif #ifdef HAVE_SYSTEM_LIBBSON php_info_print_table_row(2, "libbson headers version", BSON_VERSION_S); php_info_print_table_row(2, "libbson library version", bson_get_version()); #else php_info_print_table_row(2, "libbson version", BSON_VERSION_S); #endif php_info_print_table_end(); DISPLAY_INI_ENTRIES(); } /* }}} */ /* }}} */ /* {{{ mongodb_functions[] */ ZEND_BEGIN_ARG_INFO_EX(ai_bson_fromPHP, 0, 0, 1) ZEND_ARG_INFO(0, value) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_bson_toPHP, 0, 0, 1) ZEND_ARG_INFO(0, bson) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_bson_toJSON, 0, 0, 1) ZEND_ARG_INFO(0, bson) ZEND_END_ARG_INFO(); ZEND_BEGIN_ARG_INFO_EX(ai_bson_fromJSON, 0, 0, 1) ZEND_ARG_INFO(0, json) ZEND_END_ARG_INFO(); const zend_function_entry mongodb_functions[] = { ZEND_NS_FE(BSON_NAMESPACE, fromPHP, ai_bson_fromPHP) ZEND_NS_FE(BSON_NAMESPACE, toPHP, ai_bson_toPHP) ZEND_NS_FE(BSON_NAMESPACE, toJSON, ai_bson_toJSON) ZEND_NS_FE(BSON_NAMESPACE, fromJSON, ai_bson_fromJSON) PHP_FE_END }; /* }}} */ /* {{{ mongodb_module_entry */ zend_module_entry mongodb_module_entry = { STANDARD_MODULE_HEADER, "mongodb", mongodb_functions, PHP_MINIT(mongodb), PHP_MSHUTDOWN(mongodb), NULL /* PHP_RINIT(mongodb)*/, NULL /* PHP_RSHUTDOWN(mongodb)*/, PHP_MINFO(mongodb), MONGODB_VERSION, PHP_MODULE_GLOBALS(mongodb), PHP_GINIT(mongodb), PHP_GSHUTDOWN(mongodb), NULL, STANDARD_MODULE_PROPERTIES_EX }; /* }}} */ #ifdef COMPILE_DL_MONGODB ZEND_GET_MODULE(mongodb) #endif /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mongodb-1.1.5/php_phongo.h0000664000175000017500000002041312673034026015320 0ustar jmikolajmikola/* +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ | Copyright (c) 2014-2015 Hannes Magnusson | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Hannes Magnusson | +----------------------------------------------------------------------+ */ #ifndef PHONGO_H #define PHONGO_H /* External libs */ #include "bson.h" #include "mongoc.h" #include "mongoc-topology-description-private.h" #define phpext_mongodb_ptr &mongodb_module_entry extern zend_module_entry mongodb_module_entry; /* FIXME: Its annoying to bump version. Move into phongo_version.h.in */ #define MONGODB_VERSION_S "1.1.5" #define MONGODB_STABILITY_S "stable" #define MONGODB_VERSION MONGODB_VERSION_S #ifdef PHP_WIN32 # define PHONGO_API __declspec(dllexport) # include "ext/standard/flock_compat.h" #elif defined(__GNUC__) && __GNUC__ >= 4 # define PHONGO_API __attribute__ ((visibility("default"))) #else # define PHONGO_API #endif #ifdef ZTS # include "TSRM.h" # define PHONGO_STREAM_CTX(x) x #else # define PHONGO_STREAM_CTX(x) NULL #endif ZEND_BEGIN_MODULE_GLOBALS(mongodb) char *debug; FILE *debug_fd; bson_mem_vtable_t bsonMemVTable; ZEND_END_MODULE_GLOBALS(mongodb) #if PHP_VERSION_ID >= 70000 # define MONGODB_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(mongodb, v) #else # ifdef ZTS # define MONGODB_G(v) TSRMG(mongodb_globals_id, zend_mongodb_globals *, v) # define mglo mongodb_globals_id # else # define MONGODB_G(v) (mongodb_globals.v) # define mglo mongodb_globals # endif #endif #define PHONGO_WRITE_CONCERN_W_MAJORITY "majority" #include "php_phongo_classes.h" typedef enum { PHONGO_ERROR_INVALID_ARGUMENT = 1, PHONGO_ERROR_RUNTIME = 2, PHONGO_ERROR_UNEXPECTED_VALUE = 8, PHONGO_ERROR_MONGOC_FAILED = 3, PHONGO_ERROR_WRITE_FAILED = 5, PHONGO_ERROR_CONNECTION_FAILED = 7, PHONGO_ERROR_LOGIC = 9 } php_phongo_error_domain_t; typedef struct { void (*writer)(mongoc_stream_t *stream, int32_t timeout_msec, ssize_t sent, size_t iovcnt); } php_phongo_stream_logger; typedef struct { mongoc_stream_t vtable; php_stream *stream; const mongoc_uri_t *uri; const mongoc_host_list_t *host; #if ZTS void ***tsrm_ls; #endif } php_phongo_stream_socket; PHONGO_API zend_class_entry* phongo_exception_from_mongoc_domain(uint32_t /* mongoc_error_domain_t */ domain, uint32_t /* mongoc_error_code_t */ code); PHONGO_API zend_class_entry* phongo_exception_from_phongo_domain(php_phongo_error_domain_t domain); void phongo_throw_exception(php_phongo_error_domain_t domain TSRMLS_DC, const char *format, ...) #if PHP_VERSION_ID < 70000 # ifndef PHP_WIN32 # ifdef ZTS __attribute__ ((format(printf, 3, 4))) # else __attribute__ ((format(printf, 2, 3))) # endif # endif #endif ; void phongo_throw_exception_from_bson_error_t(bson_error_t *error TSRMLS_DC); PHONGO_API zend_object_handlers *phongo_get_std_object_handlers(void); void phongo_server_init (zval *return_value, mongoc_client_t *client, int server_id TSRMLS_DC); void phongo_readconcern_init (zval *return_value, const mongoc_read_concern_t *read_concern TSRMLS_DC); void phongo_readpreference_init (zval *return_value, const mongoc_read_prefs_t *read_prefs TSRMLS_DC); void phongo_writeconcern_init (zval *return_value, const mongoc_write_concern_t *write_concern TSRMLS_DC); bool phongo_query_init (php_phongo_query_t *query, bson_t *filter, bson_t *options TSRMLS_DC); mongoc_bulk_operation_t* phongo_bulkwrite_init (zend_bool ordered); bool phongo_execute_write (mongoc_client_t *client, const char *namespace, mongoc_bulk_operation_t *bulk, const mongoc_write_concern_t *write_concern, int server_id, zval *return_value, int return_value_used TSRMLS_DC); int phongo_execute_command (mongoc_client_t *client, const char *db, const bson_t *command, const mongoc_read_prefs_t *read_preference, int server_id, zval *return_value, int return_value_used TSRMLS_DC); int phongo_execute_query (mongoc_client_t *client, const char *namespace, const php_phongo_query_t *query, const mongoc_read_prefs_t *read_preference, int server_id, zval *return_value, int return_value_used TSRMLS_DC); mongoc_stream_t* phongo_stream_initiator (const mongoc_uri_t *uri, const mongoc_host_list_t *host, void *user_data, bson_error_t *error); const mongoc_read_concern_t* phongo_read_concern_from_zval (zval *zread_concern TSRMLS_DC); const mongoc_read_prefs_t* phongo_read_preference_from_zval(zval *zread_preference TSRMLS_DC); const mongoc_write_concern_t* phongo_write_concern_from_zval (zval *zwrite_concern TSRMLS_DC); const php_phongo_query_t* phongo_query_from_zval (zval *zquery TSRMLS_DC); void php_phongo_server_to_zval(zval *retval, const mongoc_server_description_t *sd); void php_phongo_read_concern_to_zval(zval *retval, const mongoc_read_concern_t *read_concern); void php_phongo_read_preference_to_zval(zval *retval, const mongoc_read_prefs_t *read_prefs); void php_phongo_write_concern_to_zval(zval *retval, const mongoc_write_concern_t *write_concern); void php_phongo_cursor_to_zval(zval *retval, const mongoc_cursor_t *cursor); bool phongo_manager_init(php_phongo_manager_t *manager, const char *uri_string, bson_t *bson_options, zval *driverOptions TSRMLS_DC); void php_phongo_objectid_new_from_oid(zval *object, const bson_oid_t *oid TSRMLS_DC); void php_phongo_cursor_id_new_from_id(zval *object, int64_t cursorid TSRMLS_DC); void php_phongo_new_utcdatetime_from_epoch(zval *object, int64_t msec_since_epoch TSRMLS_DC); void php_phongo_new_datetime_from_utcdatetime(zval *object, int64_t milliseconds TSRMLS_DC); void php_phongo_new_timestamp_from_increment_and_timestamp(zval *object, uint32_t increment, uint32_t timestamp TSRMLS_DC); void php_phongo_new_javascript_from_javascript(int init, zval *object, const char *code, size_t code_len TSRMLS_DC); void php_phongo_new_javascript_from_javascript_and_scope(int init, zval *object, const char *code, size_t code_len, const bson_t *scope TSRMLS_DC); void php_phongo_new_binary_from_binary_and_type(zval *object, const char *data, size_t data_len, bson_subtype_t type TSRMLS_DC); void php_phongo_new_regex_from_regex_and_options(zval *object, const char *pattern, const char *flags TSRMLS_DC); zend_bool phongo_writeerror_init(zval *return_value, bson_t *bson TSRMLS_DC); zend_bool phongo_writeconcernerror_init(zval *return_value, bson_t *bson TSRMLS_DC); void php_phongo_cursor_free(php_phongo_cursor_t *cursor); zend_object_iterator* php_phongo_cursor_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC); #if PHP_VERSION_ID >= 70000 #define PHONGO_CE_INIT(ce) do { \ ce->ce_flags |= ZEND_ACC_FINAL; \ ce->serialize = zend_class_serialize_deny; \ ce->unserialize = zend_class_unserialize_deny; \ } while(0); #else #define PHONGO_CE_INIT(ce) do { \ ce->ce_flags |= ZEND_ACC_FINAL_CLASS; \ ce->serialize = zend_class_serialize_deny; \ ce->unserialize = zend_class_unserialize_deny; \ } while(0); #endif #ifdef PHP_DEBUG void _phongo_debug_bson(bson_t *bson); #else #define _phongo_debug_bson(bson) #endif PHP_MINIT_FUNCTION(bson); #endif /* PHONGO_H */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mongodb-1.1.5/php_phongo_classes.h0000664000175000017500000003243012673034026017037 0ustar jmikolajmikola/* +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ | Copyright (c) 2014-2015 Hannes Magnusson | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Hannes Magnusson | +----------------------------------------------------------------------+ */ #ifndef PHONGO_CLASSES_H #define PHONGO_CLASSES_H #if PHP_VERSION_ID >= 70000 # include "php_phongo_structs-7.h" # define Z_COMMAND_OBJ_P(zv) php_command_fetch_object(Z_OBJ_P(zv)); # define Z_CURSOR_OBJ_P(zv) php_cursor_fetch_object(Z_OBJ_P(zv)); # define Z_CURSORID_OBJ_P(zv) php_cursorid_fetch_object(Z_OBJ_P(zv)); # define Z_MANAGER_OBJ_P(zv) php_manager_fetch_object(Z_OBJ_P(zv)); # define Z_QUERY_OBJ_P(zv) php_query_fetch_object(Z_OBJ_P(zv)); # define Z_READCONCERN_OBJ_P(zv) php_readconcern_fetch_object(Z_OBJ_P(zv)); # define Z_READPREFERENCE_OBJ_P(zv) php_readpreference_fetch_object(Z_OBJ_P(zv)); # define Z_SERVER_OBJ_P(zv) php_server_fetch_object(Z_OBJ_P(zv)); # define Z_BULKWRITE_OBJ_P(zv) php_bulkwrite_fetch_object(Z_OBJ_P(zv)); # define Z_WRITECONCERN_OBJ_P(zv) php_writeconcern_fetch_object(Z_OBJ_P(zv)); # define Z_WRITECONCERNERROR_OBJ_P(zv) php_writeconcernerror_fetch_object(Z_OBJ_P(zv)); # define Z_WRITEERROR_OBJ_P(zv) php_writeerror_fetch_object(Z_OBJ_P(zv)); # define Z_WRITERESULT_OBJ_P(zv) php_writeresult_fetch_object(Z_OBJ_P(zv)); # define Z_BINARY_OBJ_P(zv) php_binary_fetch_object(Z_OBJ_P(zv)); # define Z_INT32_OBJ_P(zv) php_int32_fetch_object(Z_OBJ_P(zv)); # define Z_INT64_OBJ_P(zv) php_int64_fetch_object(Z_OBJ_P(zv)); # define Z_JAVASCRIPT_OBJ_P(zv) php_javascript_fetch_object(Z_OBJ_P(zv)); # define Z_LOG_OBJ_P(zv) php_log_fetch_object(Z_OBJ_P(zv)); # define Z_MAXKEY_OBJ_P(zv) php_maxkey_fetch_object(Z_OBJ_P(zv)); # define Z_MINKEY_OBJ_P(zv) php_minkey_fetch_object(Z_OBJ_P(zv)); # define Z_OBJECTID_OBJ_P(zv) php_objectid_fetch_object(Z_OBJ_P(zv)); # define Z_REGEX_OBJ_P(zv) php_regex_fetch_object(Z_OBJ_P(zv)); # define Z_TIMESTAMP_OBJ_P(zv) php_timestamp_fetch_object(Z_OBJ_P(zv)); # define Z_UTCDATETIME_OBJ_P(zv) php_utcdatetime_fetch_object(Z_OBJ_P(zv)); # define Z_OBJ_COMMAND(zo) php_command_fetch_object(zo); # define Z_OBJ_CURSOR(zo) php_cursor_fetch_object(zo); # define Z_OBJ_CURSORID(zo) php_cursorid_fetch_object(zo); # define Z_OBJ_MANAGER(zo) php_manager_fetch_object(zo); # define Z_OBJ_QUERY(zo) php_query_fetch_object(zo); # define Z_OBJ_READCONCERN(zo) php_readconcern_fetch_object(zo); # define Z_OBJ_READPREFERENCE(zo) php_readpreference_fetch_object(zo); # define Z_OBJ_SERVER(zo) php_server_fetch_object(zo); # define Z_OBJ_BULKWRITE(zo) php_bulkwrite_fetch_object(zo); # define Z_OBJ_WRITECONCERN(zo) php_writeconcern_fetch_object(zo); # define Z_OBJ_WRITECONCERNERROR(zo) php_writeconcernerror_fetch_object(zo); # define Z_OBJ_WRITEERROR(zo) php_writeerror_fetch_object(zo); # define Z_OBJ_WRITERESULT(zo) php_writeresult_fetch_object(zo); # define Z_OBJ_BINARY(zo) php_binary_fetch_object(zo); # define Z_OBJ_INT32(zo) php_int32_fetch_object(zo); # define Z_OBJ_INT64(zo) php_int64_fetch_object(zo); # define Z_OBJ_JAVASCRIPT(zo) php_javascript_fetch_object(zo); # define Z_OBJ_LOG(zo) php_log_fetch_object(zo); # define Z_OBJ_MAXKEY(zo) php_maxkey_fetch_object(zo); # define Z_OBJ_MINKEY(zo) php_minkey_fetch_object(zo); # define Z_OBJ_OBJECTID(zo) php_objectid_fetch_object(zo); # define Z_OBJ_REGEX(zo) php_regex_fetch_object(zo); # define Z_OBJ_TIMESTAMP(zo) php_timestamp_fetch_object(zo); # define Z_OBJ_UTCDATETIME(zo) php_utcdatetime_fetch_object(zo); #else # include "php_phongo_structs-5.h" # define Z_COMMAND_OBJ_P(zv) (php_phongo_command_t *)zend_object_store_get_object(zv TSRMLS_CC); # define Z_CURSOR_OBJ_P(zv) (php_phongo_cursor_t *)zend_object_store_get_object(zv TSRMLS_CC); # define Z_CURSORID_OBJ_P(zv) (php_phongo_cursorid_t *)zend_object_store_get_object(zv TSRMLS_CC); # define Z_MANAGER_OBJ_P(zv) (php_phongo_manager_t *)zend_object_store_get_object(zv TSRMLS_CC); # define Z_QUERY_OBJ_P(zv) (php_phongo_query_t *)zend_object_store_get_object(zv TSRMLS_CC); # define Z_READCONCERN_OBJ_P(zv) (php_phongo_readconcern_t *)zend_object_store_get_object(zv TSRMLS_CC); # define Z_READPREFERENCE_OBJ_P(zv) (php_phongo_readpreference_t *)zend_object_store_get_object(zv TSRMLS_CC); # define Z_SERVER_OBJ_P(zv) (php_phongo_server_t *)zend_object_store_get_object(zv TSRMLS_CC); # define Z_BULKWRITE_OBJ_P(zv) (php_phongo_bulkwrite_t *)zend_object_store_get_object(zv TSRMLS_CC); # define Z_WRITECONCERN_OBJ_P(zv) (php_phongo_writeconcern_t *)zend_object_store_get_object(zv TSRMLS_CC); # define Z_WRITECONCERNERROR_OBJ_P(zv) (php_phongo_writeconcernerror_t *)zend_object_store_get_object(zv TSRMLS_CC); # define Z_WRITEERROR_OBJ_P(zv) (php_phongo_writeerror_t *)zend_object_store_get_object(zv TSRMLS_CC); # define Z_WRITERESULT_OBJ_P(zv) (php_phongo_writeresult_t *)zend_object_store_get_object(zv TSRMLS_CC); # define Z_BINARY_OBJ_P(zv) (php_phongo_binary_t *)zend_object_store_get_object(zv TSRMLS_CC); # define Z_INT32_OBJ_P(zv) (php_phongo_int32_t *)zend_object_store_get_object(zv TSRMLS_CC); # define Z_INT64_OBJ_P(zv) (php_phongo_int64_t *)zend_object_store_get_object(zv TSRMLS_CC); # define Z_JAVASCRIPT_OBJ_P(zv) (php_phongo_javascript_t *)zend_object_store_get_object(zv TSRMLS_CC); # define Z_LOG_OBJ_P(zv) (php_phongo_log_t *)zend_object_store_get_object(zv TSRMLS_CC); # define Z_MAXKEY_OBJ_P(zv) (php_phongo_maxkey_t *)zend_object_store_get_object(zv TSRMLS_CC); # define Z_MINKEY_OBJ_P(zv) (php_phongo_minkey_t *)zend_object_store_get_object(zv TSRMLS_CC); # define Z_OBJECTID_OBJ_P(zv) (php_phongo_objectid_t *)zend_object_store_get_object(zv TSRMLS_CC); # define Z_REGEX_OBJ_P(zv) (php_phongo_regex_t *)zend_object_store_get_object(zv TSRMLS_CC); # define Z_TIMESTAMP_OBJ_P(zv) (php_phongo_timestamp_t *)zend_object_store_get_object(zv TSRMLS_CC); # define Z_UTCDATETIME_OBJ_P(zv) (php_phongo_utcdatetime_t *)zend_object_store_get_object(zv TSRMLS_CC); # define Z_OBJ_COMMAND(zo) (php_phongo_command_t *)zo; # define Z_OBJ_CURSOR(zo) (php_phongo_cursor_t *)zo; # define Z_OBJ_CURSORID(zo) (php_phongo_cursorid_t *)zo; # define Z_OBJ_MANAGER(zo) (php_phongo_manager_t *)zo; # define Z_OBJ_QUERY(zo) (php_phongo_query_t *)zo; # define Z_OBJ_READCONCERN(zo) (php_phongo_readconcern_t *)zo; # define Z_OBJ_READPREFERENCE(zo) (php_phongo_readpreference_t *)zo; # define Z_OBJ_SERVER(zo) (php_phongo_server_t *)zo; # define Z_OBJ_BULKWRITE(zo) (php_phongo_bulkwrite_t *)zo; # define Z_OBJ_WRITECONCERN(zo) (php_phongo_writeconcern_t *)zo; # define Z_OBJ_WRITECONCERNERROR(zo) (php_phongo_writeconcernerror_t *)zo; # define Z_OBJ_WRITEERROR(zo) (php_phongo_writeerror_t *)zo; # define Z_OBJ_WRITERESULT(zo) (php_phongo_writeresult_t *)zo; # define Z_OBJ_BINARY(zo) (php_phongo_binary_t *)zo; # define Z_OBJ_INT32(zo) (php_phongo_int32_t *)zo; # define Z_OBJ_INT64(zo) (php_phongo_int64_t *)zo; # define Z_OBJ_JAVASCRIPT(zo) (php_phongo_javascript_t *)zo; # define Z_OBJ_LOG(zo) (php_phongo_log_t *)zo; # define Z_OBJ_MAXKEY(zo) (php_phongo_maxkey_t *)zo; # define Z_OBJ_MINKEY(zo) (php_phongo_minkey_t *)zo; # define Z_OBJ_OBJECTID(zo) (php_phongo_objectid_t *)zo; # define Z_OBJ_REGEX(zo) (php_phongo_regex_t *)zo; # define Z_OBJ_TIMESTAMP(zo) (php_phongo_timestamp_t *)zo; # define Z_OBJ_UTCDATETIME(zo) (php_phongo_utcdatetime_t *)zo; #endif typedef struct { zend_object_iterator intern; php_phongo_cursor_t *cursor; long current; } php_phongo_cursor_iterator; extern PHONGO_API zend_class_entry *php_phongo_command_ce; extern PHONGO_API zend_class_entry *php_phongo_cursor_ce; extern PHONGO_API zend_class_entry *php_phongo_cursorid_ce; extern PHONGO_API zend_class_entry *php_phongo_manager_ce; extern PHONGO_API zend_class_entry *php_phongo_query_ce; extern PHONGO_API zend_class_entry *php_phongo_readconcern_ce; extern PHONGO_API zend_class_entry *php_phongo_readpreference_ce; extern PHONGO_API zend_class_entry *php_phongo_result_ce; extern PHONGO_API zend_class_entry *php_phongo_server_ce; extern PHONGO_API zend_class_entry *php_phongo_bulkwrite_ce; extern PHONGO_API zend_class_entry *php_phongo_writeconcern_ce; extern PHONGO_API zend_class_entry *php_phongo_writeconcernerror_ce; extern PHONGO_API zend_class_entry *php_phongo_writeerror_ce; extern PHONGO_API zend_class_entry *php_phongo_writeresult_ce; extern PHONGO_API zend_class_entry *php_phongo_exception_ce; extern PHONGO_API zend_class_entry *php_phongo_logicexception_ce; extern PHONGO_API zend_class_entry *php_phongo_runtimeexception_ce; extern PHONGO_API zend_class_entry *php_phongo_unexpectedvalueexception_ce; extern PHONGO_API zend_class_entry *php_phongo_invalidargumentexception_ce; extern PHONGO_API zend_class_entry *php_phongo_connectionexception_ce; extern PHONGO_API zend_class_entry *php_phongo_authenticationexception_ce; extern PHONGO_API zend_class_entry *php_phongo_sslconnectionexception_ce; extern PHONGO_API zend_class_entry *php_phongo_executiontimeoutexception_ce; extern PHONGO_API zend_class_entry *php_phongo_connectiontimeoutexception_ce; extern PHONGO_API zend_class_entry *php_phongo_writeexception_ce; extern PHONGO_API zend_class_entry *php_phongo_bulkwriteexception_ce; extern PHONGO_API zend_class_entry *php_phongo_type_ce; extern PHONGO_API zend_class_entry *php_phongo_persistable_ce; extern PHONGO_API zend_class_entry *php_phongo_unserializable_ce; extern PHONGO_API zend_class_entry *php_phongo_serializable_ce; extern PHONGO_API zend_class_entry *php_phongo_binary_ce; extern PHONGO_API zend_class_entry *php_phongo_int32_ce; extern PHONGO_API zend_class_entry *php_phongo_int64_ce; extern PHONGO_API zend_class_entry *php_phongo_javascript_ce; extern PHONGO_API zend_class_entry *php_phongo_log_ce; extern PHONGO_API zend_class_entry *php_phongo_maxkey_ce; extern PHONGO_API zend_class_entry *php_phongo_minkey_ce; extern PHONGO_API zend_class_entry *php_phongo_objectid_ce; extern PHONGO_API zend_class_entry *php_phongo_regex_ce; extern PHONGO_API zend_class_entry *php_phongo_timestamp_ce; extern PHONGO_API zend_class_entry *php_phongo_utcdatetime_ce; /* Shared across all MongoDB\Driver objects to disable unserialize() */ PHP_METHOD(Manager, __wakeUp); /* Shared across all final MongoDB\Driver value objects, only possible to construct them internally */ PHP_METHOD(Server, __construct); PHP_MINIT_FUNCTION(Command); PHP_MINIT_FUNCTION(Cursor); PHP_MINIT_FUNCTION(CursorId); PHP_MINIT_FUNCTION(Manager); PHP_MINIT_FUNCTION(Query); PHP_MINIT_FUNCTION(ReadConcern); PHP_MINIT_FUNCTION(ReadPreference); PHP_MINIT_FUNCTION(Result); PHP_MINIT_FUNCTION(Server); PHP_MINIT_FUNCTION(BulkWrite); PHP_MINIT_FUNCTION(WriteConcern); PHP_MINIT_FUNCTION(WriteConcernError); PHP_MINIT_FUNCTION(WriteError); PHP_MINIT_FUNCTION(WriteResult); PHP_MINIT_FUNCTION(Exception); PHP_MINIT_FUNCTION(LogicException); PHP_MINIT_FUNCTION(RuntimeException); PHP_MINIT_FUNCTION(UnexpectedValueException); PHP_MINIT_FUNCTION(InvalidArgumentException); PHP_MINIT_FUNCTION(ConnectionException); PHP_MINIT_FUNCTION(AuthenticationException); PHP_MINIT_FUNCTION(SSLConnectionException); PHP_MINIT_FUNCTION(ExecutionTimeoutException); PHP_MINIT_FUNCTION(ConnectionTimeoutException); PHP_MINIT_FUNCTION(WriteException); PHP_MINIT_FUNCTION(BulkWriteException); PHP_MINIT_FUNCTION(Type); PHP_MINIT_FUNCTION(Unserializable); PHP_MINIT_FUNCTION(Serializable); PHP_MINIT_FUNCTION(Persistable); PHP_MINIT_FUNCTION(Binary); PHP_MINIT_FUNCTION(Javascript); PHP_MINIT_FUNCTION(MaxKey); PHP_MINIT_FUNCTION(MinKey); PHP_MINIT_FUNCTION(ObjectID); PHP_MINIT_FUNCTION(Regex); PHP_MINIT_FUNCTION(Timestamp); PHP_MINIT_FUNCTION(UTCDateTime); #endif /* PHONGO_CLASSES_H */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mongodb-1.1.5/php_phongo_structs-5.h0000664000175000017500000001224312673034026017253 0ustar jmikolajmikola/* +---------------------------------------------------------------------------+ | PHP Driver for MongoDB | +---------------------------------------------------------------------------+ | Copyright 2015 MongoDB, Inc. | | | | Licensed under the Apache License, Version 2.0 (the "License"); | | you may not use this file except in compliance with the License. | | You may obtain a copy of the License at | | | | http://www.apache.org/licenses/LICENSE-2.0 | | | | Unless required by applicable law or agreed to in writing, software | | distributed under the License is distributed on an "AS IS" BASIS, | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | See the License for the specific language governing permissions and | | limitations under the License. | +---------------------------------------------------------------------------+ | Copyright (c) 2015 MongoDB, Inc. | +---------------------------------------------------------------------------+ */ #ifndef PHONGO_STRUCTS_H #define PHONGO_STRUCTS_H /* PHP Core stuff */ #include #include /* Our stuffz */ #include "php_bson.h" typedef struct { zend_object std; bson_t *bson; } php_phongo_command_t; typedef struct { zend_object std; mongoc_cursor_t *cursor; mongoc_client_t *client; int server_id; php_phongo_bson_state visitor_data; int got_iterator; } php_phongo_cursor_t; typedef struct { zend_object std; uint64_t id; } php_phongo_cursorid_t; typedef struct { zend_object std; mongoc_client_t *client; } php_phongo_manager_t; typedef struct { zend_object std; bson_t *query; bson_t *selector; mongoc_query_flags_t flags; uint32_t skip; uint32_t limit; uint32_t batch_size; mongoc_read_concern_t *read_concern; } php_phongo_query_t; typedef struct { zend_object std; mongoc_read_concern_t *read_concern; } php_phongo_readconcern_t; typedef struct { zend_object std; mongoc_read_prefs_t *read_preference; } php_phongo_readpreference_t; typedef struct { zend_object std; mongoc_client_t *client; int server_id; } php_phongo_server_t; typedef struct { zend_object std; mongoc_bulk_operation_t *bulk; } php_phongo_bulkwrite_t; typedef struct { zend_object std; mongoc_write_concern_t *write_concern; } php_phongo_writeconcern_t; typedef struct { zend_object std; int code; char *message; zval *info; } php_phongo_writeconcernerror_t; typedef struct { zend_object std; int code; char *message; zval *info; uint32_t index; } php_phongo_writeerror_t; typedef struct { zend_object std; mongoc_write_concern_t *write_concern; mongoc_write_result_t write_result; mongoc_client_t *client; int server_id; } php_phongo_writeresult_t; typedef struct { zend_object std; char *data; int data_len; uint8_t type; } php_phongo_binary_t; typedef struct { zend_object std; } php_phongo_int32_t; typedef struct { zend_object std; } php_phongo_int64_t; typedef struct { zend_object std; char *javascript; size_t javascript_len; bson_t *document; } php_phongo_javascript_t; typedef struct { zend_object std; } php_phongo_log_t; typedef struct { zend_object std; } php_phongo_maxkey_t; typedef struct { zend_object std; } php_phongo_minkey_t; typedef struct { zend_object std; char oid[25]; } php_phongo_objectid_t; typedef struct { zend_object std; char *pattern; int pattern_len; char *flags; int flags_len; } php_phongo_regex_t; typedef struct { zend_object std; uint32_t increment; uint32_t timestamp; } php_phongo_timestamp_t; typedef struct { zend_object std; int64_t milliseconds; } php_phongo_utcdatetime_t; #endif /* PHONGO_STRUCTS */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */ mongodb-1.1.5/php_phongo_structs-7.h0000664000175000017500000002252112673034026017255 0ustar jmikolajmikola/* +---------------------------------------------------------------------------+ | PHP Driver for MongoDB | +---------------------------------------------------------------------------+ | Copyright 2015 MongoDB, Inc. | | | | Licensed under the Apache License, Version 2.0 (the "License"); | | you may not use this file except in compliance with the License. | | You may obtain a copy of the License at | | | | http://www.apache.org/licenses/LICENSE-2.0 | | | | Unless required by applicable law or agreed to in writing, software | | distributed under the License is distributed on an "AS IS" BASIS, | | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | See the License for the specific language governing permissions and | | limitations under the License. | +---------------------------------------------------------------------------+ | Copyright (c) 2015 MongoDB, Inc. | +---------------------------------------------------------------------------+ */ #ifndef PHONGO_STRUCTS_H #define PHONGO_STRUCTS_H /* PHP Core stuff */ #include #include /* Our stuffz */ #include "php_bson.h" typedef struct { bson_t *bson; zend_object std; } php_phongo_command_t; typedef struct { mongoc_cursor_t *cursor; mongoc_client_t *client; int server_id; php_phongo_bson_state visitor_data; int got_iterator; zend_object std; } php_phongo_cursor_t; typedef struct { uint64_t id; zend_object std; } php_phongo_cursorid_t; typedef struct { mongoc_client_t *client; zend_object std; } php_phongo_manager_t; typedef struct { bson_t *query; bson_t *selector; mongoc_query_flags_t flags; uint32_t skip; uint32_t limit; uint32_t batch_size; mongoc_read_concern_t *read_concern; zend_object std; } php_phongo_query_t; typedef struct { mongoc_read_concern_t *read_concern; zend_object std; } php_phongo_readconcern_t; typedef struct { mongoc_read_prefs_t *read_preference; zend_object std; } php_phongo_readpreference_t; typedef struct { mongoc_client_t *client; int server_id; zend_object std; } php_phongo_server_t; typedef struct { mongoc_bulk_operation_t *bulk; zend_object std; } php_phongo_bulkwrite_t; typedef struct { mongoc_write_concern_t *write_concern; zend_object std; } php_phongo_writeconcern_t; typedef struct { int code; char *message; zval info; zend_object std; } php_phongo_writeconcernerror_t; typedef struct { int code; char *message; zval info; uint32_t index; zend_object std; } php_phongo_writeerror_t; typedef struct { mongoc_write_concern_t *write_concern; mongoc_write_result_t write_result; mongoc_client_t *client; int server_id; zend_object std; } php_phongo_writeresult_t; typedef struct { char *data; int data_len; int type; zend_object std; } php_phongo_binary_t; typedef struct { zend_object std; } php_phongo_int32_t; typedef struct { zend_object std; } php_phongo_int64_t; typedef struct { char *javascript; size_t javascript_len; bson_t *document; zend_object std; } php_phongo_javascript_t; typedef struct { zend_object std; } php_phongo_log_t; typedef struct { zend_object std; } php_phongo_maxkey_t; typedef struct { zend_object std; } php_phongo_minkey_t; typedef struct { char oid[25]; zend_object std; } php_phongo_objectid_t; typedef struct { char *pattern; int pattern_len; char *flags; int flags_len; zend_object std; } php_phongo_regex_t; typedef struct { uint32_t increment; uint32_t timestamp; zend_object std; } php_phongo_timestamp_t; typedef struct { int64_t milliseconds; zend_object std; } php_phongo_utcdatetime_t; static inline php_phongo_command_t* php_command_fetch_object(zend_object *obj) { return (php_phongo_command_t *)((char *)obj - XtOffsetOf(php_phongo_command_t, std)); } static inline php_phongo_cursor_t* php_cursor_fetch_object(zend_object *obj) { return (php_phongo_cursor_t *)((char *)obj - XtOffsetOf(php_phongo_cursor_t, std)); } static inline php_phongo_cursorid_t* php_cursorid_fetch_object(zend_object *obj) { return (php_phongo_cursorid_t *)((char *)obj - XtOffsetOf(php_phongo_cursorid_t, std)); } static inline php_phongo_manager_t* php_manager_fetch_object(zend_object *obj) { return (php_phongo_manager_t *)((char *)obj - XtOffsetOf(php_phongo_manager_t, std)); } static inline php_phongo_query_t* php_query_fetch_object(zend_object *obj) { return (php_phongo_query_t *)((char *)obj - XtOffsetOf(php_phongo_query_t, std)); } static inline php_phongo_readconcern_t* php_readconcern_fetch_object(zend_object *obj) { return (php_phongo_readconcern_t *)((char *)obj - XtOffsetOf(php_phongo_readconcern_t, std)); } static inline php_phongo_readpreference_t* php_readpreference_fetch_object(zend_object *obj) { return (php_phongo_readpreference_t *)((char *)obj - XtOffsetOf(php_phongo_readpreference_t, std)); } static inline php_phongo_server_t* php_server_fetch_object(zend_object *obj) { return (php_phongo_server_t *)((char *)obj - XtOffsetOf(php_phongo_server_t, std)); } static inline php_phongo_bulkwrite_t* php_bulkwrite_fetch_object(zend_object *obj) { return (php_phongo_bulkwrite_t *)((char *)obj - XtOffsetOf(php_phongo_bulkwrite_t, std)); } static inline php_phongo_writeconcern_t* php_writeconcern_fetch_object(zend_object *obj) { return (php_phongo_writeconcern_t *)((char *)obj - XtOffsetOf(php_phongo_writeconcern_t, std)); } static inline php_phongo_writeconcernerror_t* php_writeconcernerror_fetch_object(zend_object *obj) { return (php_phongo_writeconcernerror_t *)((char *)obj - XtOffsetOf(php_phongo_writeconcernerror_t, std)); } static inline php_phongo_writeerror_t* php_writeerror_fetch_object(zend_object *obj) { return (php_phongo_writeerror_t *)((char *)obj - XtOffsetOf(php_phongo_writeerror_t, std)); } static inline php_phongo_writeresult_t* php_writeresult_fetch_object(zend_object *obj) { return (php_phongo_writeresult_t *)((char *)obj - XtOffsetOf(php_phongo_writeresult_t, std)); } static inline php_phongo_binary_t* php_binary_fetch_object(zend_object *obj) { return (php_phongo_binary_t *)((char *)obj - XtOffsetOf(php_phongo_binary_t, std)); } static inline php_phongo_int32_t* php_int32_fetch_object(zend_object *obj) { return (php_phongo_int32_t *)((char *)obj - XtOffsetOf(php_phongo_int32_t, std)); } static inline php_phongo_int64_t* php_int64_fetch_object(zend_object *obj) { return (php_phongo_int64_t *)((char *)obj - XtOffsetOf(php_phongo_int64_t, std)); } static inline php_phongo_javascript_t* php_javascript_fetch_object(zend_object *obj) { return (php_phongo_javascript_t *)((char *)obj - XtOffsetOf(php_phongo_javascript_t, std)); } static inline php_phongo_log_t* php_log_fetch_object(zend_object *obj) { return (php_phongo_log_t *)((char *)obj - XtOffsetOf(php_phongo_log_t, std)); } static inline php_phongo_maxkey_t* php_maxkey_fetch_object(zend_object *obj) { return (php_phongo_maxkey_t *)((char *)obj - XtOffsetOf(php_phongo_maxkey_t, std)); } static inline php_phongo_minkey_t* php_minkey_fetch_object(zend_object *obj) { return (php_phongo_minkey_t *)((char *)obj - XtOffsetOf(php_phongo_minkey_t, std)); } static inline php_phongo_objectid_t* php_objectid_fetch_object(zend_object *obj) { return (php_phongo_objectid_t *)((char *)obj - XtOffsetOf(php_phongo_objectid_t, std)); } static inline php_phongo_regex_t* php_regex_fetch_object(zend_object *obj) { return (php_phongo_regex_t *)((char *)obj - XtOffsetOf(php_phongo_regex_t, std)); } static inline php_phongo_timestamp_t* php_timestamp_fetch_object(zend_object *obj) { return (php_phongo_timestamp_t *)((char *)obj - XtOffsetOf(php_phongo_timestamp_t, std)); } static inline php_phongo_utcdatetime_t* php_utcdatetime_fetch_object(zend_object *obj) { return (php_phongo_utcdatetime_t *)((char *)obj - XtOffsetOf(php_phongo_utcdatetime_t, std)); } #endif /* PHONGO_STRUCTS */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: * vim600: noet sw=4 ts=4 fdm=marker * vim<600: noet sw=4 ts=4 */